给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
输入:原始二叉树如下图
输出:合并后的二叉树如下图
注:本文中以如下所示节点表示空节点
基于递归的解决思路:
两颗树都从root开始遍历,root合并之后生成新的root节点
接下来,合并两颗树的root.left 然后连接到新root的left上,合并原始root的right节点,连接到新root的right上。
基于上面分析,定义如下递归函数。
//合并给定的两个节点
public TreeNode mergeTree(TreeNode root1, TreeNode root2) {
}
递归终止条件,如果其中一个结点为空,如root2为空,如下,则直接返回root1
基于上面分析,代码如下:
public TreeNode mergeTree(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (root2 == null) return root1;
//到此处说明root1 和 root2都不为空,所以直接生成新的root节点
TreeNode newNode = new TreeNode(root1.val + root2.val);
//递归调用mergeTree设置left和right
newNode.left = mergeTree(root1.left, root2.left);
newNode.right = mergeTree(root1.right, root2.right);
return newNode;
}
基于迭代的解决思路。
题目没有说不可以破坏原树,此处不开辟额外的空间,在原树上进行合并。我们此处假设把树root2合并到root1上。我们可以定义一个队列辅助处理。每一次队列头的两个元素分别来源于两颗二叉树。代表此次要处理的节点,如果给定两个节点,如何合并其子节点?有以下几种方式。
(1)如果root1.left 和 root2.left 都不为空,直接执行root1.left.val = root1.left.val + root2.left.val,同时把root1.left 和 root2.left 入队列即可
(2)如果root1.right和 root2.right都不为空,直接执行root1.right.val = root1.right.val + root2.right.val,同时把root1.right和 root2.right入队列即可
(3)如果root1.left 为空,则直接把root2.left设置到root1.left上即可
(4)如果root1.right为空,则直接把root2.right设置到root1.right上即可
经过上面分析,代码如下,配合注释很好理解
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null) return root2;
if (root2 == null) return root1;
//到此处说明root1和root2都不可能为空,设置root1的value属性,此时root1和root2相当于是已经合并到root1上了
root1.val = root1.val + root2.val;
Queue<TreeNode> queue = new LinkedList<>();
//root1 和 root2 分别进入队列
queue.offer(root1);
queue.offer(root2);
while (!queue.isEmpty()) {
//出队两个元素,接下来处理出队的两个元素的子节点
TreeNode node1 = queue.poll();
TreeNode node2 = queue.poll();
if (node1.left != null && node2.left != null) {
node1.left.val = node1.left.val + node2.left.val;
queue.offer(node1.left);
queue.offer(node2.left);
}
if (node1.right != null && node2.right != null) {
node1.right.val = node1.right.val + node2.right.val;
queue.offer(node1.right);
queue.offer(node2.right);
}
//如果node1的left为空,则直接设置node1.left为node2.left
if (node1.left == null) {
node1.left = node2.left;
}
//如果node1的right为空,则直接设置node1.right为node2.right
if (node1.right == null) {
node1.right = node2.right;
}
}
return root1;
}