Description
給定一棵二元樹的根節點,將整棵樹左右翻轉(鏡像),回傳翻轉後的根節點。每個節點的左右子樹互換。
Example:
Input: root = [4,2,7,1,3,6,9] Output: [4,7,2,9,6,3,1]
Intuition#
對每個節點,交換其左右子節點,然後遞迴處理子樹。
- 翻轉一棵樹 = 交換根的左右子樹 + 分別翻轉左右子樹
- 這是一個天然的遞迴結構,也可以用迭代(BFS/DFS)完成
Approaches#
⭐ 1: Recursive DFS#
- 概念: 後序遍歷,先遞迴翻轉左右子樹,再交換左右子節點
- 時間複雜度:
O(n),每個節點訪問一次 - 空間複雜度:
O(h),遞迴堆疊深度,h 為樹高
class Solution {
fun invertTree(root: TreeNode?): TreeNode? {
if (root == null) return null
val left = invertTree(root.left)
val right = invertTree(root.right)
root.left = right
root.right = left
return root
}
}2: Iterative BFS#
- 概念: 使用佇列進行層序遍歷,對每個節點交換左右子節點
- 時間複雜度:
O(n) - 空間複雜度:
O(n),佇列最多存放一層的節點
class Solution {
fun invertTree(root: TreeNode?): TreeNode? {
if (root == null) return null
val queue: ArrayDeque<TreeNode> = ArrayDeque()
queue.add(root)
while (queue.isNotEmpty()) {
val node = queue.removeFirst()
val temp = node.left
node.left = node.right
node.right = temp
node.left?.let { queue.add(it) }
node.right?.let { queue.add(it) }
}
return root
}
}🔑 Takeaways#
- Pattern: 樹的遞迴結構 — 問題可分解為「對當前節點操作 + 遞迴處理子樹」
- 關鍵技巧: 遞迴是處理樹結構最直覺的方式,幾乎所有樹的變換問題都能用這個模式