LeetCode 617. 合并二叉树
题目描述


题意分析
从两棵二叉树的根开始,按照相同的左右路径对齐节点。对应位置都有节点时,把两个值相加;只有一棵树有节点时,保留这一侧的节点及其子树;两侧都为空时,结果也为空。
返回合并后树的根节点。这里的“对应”指结构位置相同,而不是节点值相同或在各自遍历中排名相同。题目允许复用原节点,无须为结果复制一整棵独立的新树。
解法:递归原地合并
核心思路
[!blue]
定义
mergeTrees(root1, root2)返回这两个位置所代表子树的合并结果。递归中的两个参数始终处于各自原树的同一结构位置,左孩子只与左孩子合并,右孩子只与右孩子合并。若
root1为空,当前位置及其后续只可能由第二棵树提供,直接返回root2;反之返回root1。这不只是空指针边界,也表示无需继续遍历这棵单独存在的子树,它本身就是正确结果。两侧都为空也由上述分支自然处理。两侧都存在时,复用
root1作为结果节点,把root2的值加到它上面。然后分别递归合并左右孩子,并把递归返回值接回root1.left、root1.right。仅调用递归而不接收返回值是不够的:当第一棵树缺少某个孩子时,需要靠返回值把第二棵树独有的子树挂上来。左右递归都完成后,当前节点的值和两棵结果子树就都符合合并规则,返回
root1供上一层继续连接。整个过程只向同时存在的节点对深入,不处理无需合并的单侧区域。该实现会修改第一棵树重叠位置的节点值和孩子连接,并可能直接挂入第二棵树的子树。因此结果会复用输入节点,附接部分与第二棵树共享引用;它不保证结果是一份与输入完全独立的副本。
解题步骤
- 第一侧为空时返回第二侧;第二侧为空时返回第一侧。
- 两侧都存在时,执行
root1.val += root2.val。- 将两个左孩子的递归合并结果赋给
root1.left。- 将两个右孩子的递归合并结果赋给
root1.right。- 返回当前复用的
root1。
代码实现
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) {
return root2;
}
if (root2 == null) {
return root1;
}
// 复用 root1 节点作为合并后的节点。
root1.val += root2.val;
// 接住递归返回值,才能挂入第二棵树独有的子树。
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
return root1;
}
}
func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
if root1 == nil {
return root2
}
if root2 == nil {
return root1
}
// 两个节点都存在时,值相加并继续合并子树。
root1.Val += root2.Val
// 接住递归返回值,才能挂入第二棵树独有的子树。
root1.Left = mergeTrees(root1.Left, root2.Left)
root1.Right = mergeTrees(root1.Right, root2.Right)
return root1
}
复杂度分析
- 时间复杂度:$O(r + 1)$,其中
r为两个位置都存在节点的重叠节点对数量。每个重叠节点只继续调用左右两次,遇到单侧为空即常量时间返回,不会遍历整棵非重叠子树。- 空间复杂度:$O(h + 1)$,其中
h为重叠区域沿根向下的最大深度。空间来自递归栈,不额外创建结果节点;若两树节点数为m、n,最坏为 $O(\min(m, n) + 1)$。
关键点总结
[!green]
- 合并按结构位置同步递归,单侧为空时直接采用另一棵子树。
- 递归返回的是该位置的新子树入口,父节点必须接住返回值。
- 复用节点避免复制非重叠区域,同时也意味着结果和输入可能共享子树。
易错点总结
[!yellow]
- 只在两侧都为空时返回,会在仅一侧为空时仍访问空节点的值或孩子。
- 一侧为空却返回空,会丢掉另一侧本应保留的整棵子树。
- 只递归调用、不赋值给当前孩子,无法连接第一棵树原本缺失的那一侧。
- 把不同方向的孩子配对,会改变题目按同一结构位置合并的含义。
- 将返回树当成深拷贝继续修改,可能同时改变其复用的输入节点,应明确当前方法的共享关系。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 100. 相同的树 | 简单 | 同样同步遍历两棵树,本题在节点都存在时合并值,并处理只有一侧存在的子树。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!