Description
給定兩棵二元樹,將它們合併成一棵新樹。合併規則:若兩個節點重疊,則將它們的值相加;若只有一方有節點,則使用該節點。
Example:
Input: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7] Output: [3,4,5,5,4,null,7]
Intuition#
同時遍歷兩棵樹,對應位置的節點值相加,遞迴合併左右子樹。
- 若其中一棵為 null,直接回傳另一棵
- 若兩棵都存在,建立新節點(值相加),遞迴處理左右子樹
Approaches#
⭐ 1: Recursive DFS#
- 概念: 同時遞迴兩棵樹,合併對應節點
- 時間複雜度:
O(min(m, n)),m、n 為兩棵樹的節點數,只遍歷重疊部分 - 空間複雜度:
O(min(h1, h2)),遞迴深度取決於較矮的樹
class Solution {
fun mergeTrees(root1: TreeNode?, root2: TreeNode?): TreeNode? {
if (root1 == null) return root2
if (root2 == null) return root1
val merged = TreeNode(root1.`val` + root2.`val`)
merged.left = mergeTrees(root1.left, root2.left)
merged.right = mergeTrees(root1.right, root2.right)
return merged
}
}2: Iterative BFS#
- 概念: 使用佇列同時遍歷兩棵樹,直接修改第一棵樹
- 時間複雜度:
O(min(m, n)) - 空間複雜度:
O(min(m, n))
class Solution {
fun mergeTrees(root1: TreeNode?, root2: TreeNode?): TreeNode? {
if (root1 == null) return root2
if (root2 == null) return root1
val queue = ArrayDeque<Pair<TreeNode, TreeNode>>()
queue.add(root1 to root2)
while (queue.isNotEmpty()) {
val (n1, n2) = queue.removeFirst()
n1.`val` += n2.`val`
if (n1.left != null && n2.left != null) {
queue.add(n1.left!! to n2.left!!)
} else if (n1.left == null) {
n1.left = n2.left
}
if (n1.right != null && n2.right != null) {
queue.add(n1.right!! to n2.right!!)
} else if (n1.right == null) {
n1.right = n2.right
}
}
return root1
}
}🔑 Takeaways#
- Pattern: 同時遍歷兩棵樹 — 對應節點配對處理
- 關鍵技巧: 處理兩棵樹的問題時,null 檢查是關鍵:一方為 null 時直接回傳另一方