问题
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL
的节点将直接作为新二叉树的节点
示例 1:
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始
解法一:递归
确定递归函数的参数和返回值
- 首先那么要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点
TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
- 首先那么要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点
确定终止条件:
- 因为是传入了两个树,那么就有两个树遍历的节点
t1
和t2
,如果t1 == null
,两个树合并就应该是t2
(如果t2
也为null
也无所谓,合并之后就是null
) - 反过来如果
t2 == null
,那么两个数合并就是t1
(如果t1
也为null
也无妨,合并之后就是null
)if (t1 == null) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == null) return t1; // 如果t2为空,合并之后就应该是t1
- 因为是传入了两个树,那么就有两个树遍历的节点
确定单层递归的逻辑:
单层递归的逻辑就比较好些了,这里我们用重复利用一下
t1
这个树,t1
就是合并之后树的根节点(就是修改了原来树的结构) ,那么单层递归中,就要把两棵树的元素加到一起t1.val += t2.val;
接下来
t1
的左子树是:合并t1
左子树t2
左子树之后的左子树t1
的右子树:是合并t1
右子树t2
右子树之后的右子树- 最终
t1
就是合并之后的根节点t1.left = mergeTrees(t1.left, t2.left);
t1.right = mergeTrees(t1.right, t2.right);
return t1;
前序遍历
class Solution {
TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null)
return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == null)
return t1; // 如果t2为空,合并之后就应该是t1
// 修改了t1的数值和结构
t1.val += t2.val; // 中
t1.left = mergeTrees(t1.left, t2.left); // 左
t1.right = mergeTrees(t1.right, t2.right); // 右
return t1;
}
}
也可以不修改t1
和t2
的数据结构,重新定义一个树
class Solution {
TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null)
return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == null)
return t1; // 如果t2为空,合并之后就应该是t1
// 修改了t1的数值和结构
TreeNode root = new TreeNode(0);
root.val = t1.val + t2.val;
root.left = mergeTrees(t1.left, t2.left);
root.right = mergeTrees(t1.right, t2.right);
return root;
}
}
解法二:层序遍历
class Solution {
TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null)
return t2;
if (t2 == null)
return t1;
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(t1);
queue.offer(t2);
while(!queue.isEmpty()) {
TreeNode node1 = queue.poll();
TreeNode node2 = queue.poll();
// 此时两个节点一定不为空,val相加
node1.val += node2.val;
// 如果两棵树左节点都不为空,加入队列
if (node1.left != null && node2.left != null) {
queue.offer(node1.left);
queue.offer(node2.left);
}
// 如果两棵树右节点都不为空,加入队列
if (node1.right != null && node2.right != null) {
queue.offer(node1.right);
queue.offer(node2.right);
}
// 当t1的左节点为空 t2左节点不为空,就赋值过去
if (node1.left == null && node2.left != null) {
node1.left = node2.left;
}
// 当t1的右节点 为空 t2右节点不为空,就赋值过去
if (node1.right == null && node2.right != null) {
node1.right = node2.right;
}
}
return t1;
}
}