一,题目:
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]示例 2:
输入:root1 = [1], root2 = [1,2]
输出:[2,2]
提示:
两棵树中的节点数目在范围 [0, 2000] 内
-104 <= Node.val <= 104
通过次数224,567提交次数285,269来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-binary-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二,解题思路:
深度优先搜索解法:
可以使用深度优先搜索合并两个二叉树。
从根节点开始同时遍历两个二叉树,并将对应的节点进行合并。
- 如果两个二叉树的对应节点都不为空,则合并后的二叉树的对应节点的值为两个二叉树的对应节点的值之和;
-
如果两个二叉树的对应节点都为空,则合并后的二叉树的对应节点也为空;
-
如果两个二叉树的对应节点有一个为空,则合并后的二叉树的对应节点为其中的非空节点;
对一个节点进行合并之后,还要对该节点的左右子树分别进行合并:
- 如果此时两个二叉树的该节点都不为空,那么合并新节点的左右子节点是一个递归的过程。
- 如果此时两个二叉树的该节点有一个为空,那么合并新节点的左右子节点与非空节点的左右子节点是一样的;
举例:
1,合并节点1和节点10,合成新节点11;
因为节点1和节点10都不为null,所以执行递归操作,合并新节点11的左节点和右节点;
1.1,合并新节点11的左节点:
将节点2与节点11合并,形成新节点13,为新节点11的左子结点;
因为节点2和节点11都不为null,所以执行递归操作,合并新节点13的左节点和右节点;
1.1.1,合并新节点13的左节点:
将节点4与null进行合并,形成新节点4;
由于存在其中一个为null,所以将非空节点的左子结点和右子节点直接设为新节点4的左右子节点;
1.1.1,合并新节点13的右节点:
将节点5与null进行合并,形成新节点5;
由于存在其中一个为null,所以将非空节点的左子结点和右子节点直接设为新节点5的左右子节点;
此时新二叉树如图所示:
1.2,合并新节点11的右节点:
将节点3与节点12合并,形成新节点15,为新节点11的右子结点;
因为节点3与节点12都不为null,所以执行递归操作,合并新节点15的左节点和右节点;
...
以此类推。
最终:
三,代码:
/**
* 力扣官方解法:
* @param t1
* @param t2
* @return
*/
public static TreeNode mergeTrees2(TreeNode t1, TreeNode t2) {
if (t1 == null) {
return t2;
}
if (t2 == null) {
return t1;
}
TreeNode merged = new TreeNode(t1.val + t2.val);
merged.left = mergeTrees2(t1.left, t2.left);
merged.right = mergeTrees2(t1.right, t2.right);
return merged;
}
/**
* 合并二叉树
* @param node1
* @param node2
* @return
*/
public TreeNode mergeTrees(TreeNode node1, TreeNode node2) {
TreeNode newNode = null;
if (node1 != null || node2 != null) {
//如果左右两边的该位置的节点都不为空
if (node1 != null && node2 != null) {
//合并为一个新节点:
newNode = new TreeNode(node1.val + node2.val);
//合成该节点的左右子节点:
TreeNode leftNode = mergeTrees(node1.left, node2.left);
TreeNode rightNode = mergeTrees(node1.right, node2.right);
newNode.left = leftNode;
newNode.right = rightNode;
}
//如果左边的节点不为空,右边的为空,则左边的为新节点:
else if (node1 != null && node2 == null) {
newNode = node1;
//合成该节点的左右子节点:
newNode.left = node1.left;
newNode.right = node1.right;
}
//如果右边的节点不为空,左边的为空,则右边的为新节点:
else if (node1 == null && node2 != null) {
newNode = node2;
//合成该节点的左右子节点:
newNode.left = node2.left;
newNode.right = node2.right;
}
}
//如果左右都为空:
else {
newNode = null; //这一步其实可省略;
}
return newNode;
}