问题
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 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为空,合并之后就应该是t2if (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为空,合并之后就应该是t2if (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为空,合并之后就应该是t2if (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;}}
