二叉树--合并二叉树

Posted 算法和数据结构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树--合并二叉树相关的知识,希望对你有一定的参考价值。

来源:LeetCode

难度:简单

描述:

        给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

        你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。


示例1:


分析:

        题目就是让咱们合并两棵二叉树,要求是同一个位置两棵树都有节点的话节点值相加,如果只有一棵树有节点,那么就用该节点作为新二叉树的节点,都没有节点则跳过

        需要注意的是,由于二叉树有左右两个分支,所以在合并的时候咱们需要指定当前节点是新二叉树的左节点还是右节点,同样,这里介绍深度和广度两种方法来解题,如下


解题

方法一:深度优先遍历

思路:利用递归的方式对两棵树同时遍历,分别计算每个节点值,当其中一棵树的某个节点为空时,直接返回另一棵树对应位置的即可


代码:

 1public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
2    //root1节点为空,使用root2的节点
3    if (root1 == null) {
4        return root2;
5    }
6    //root2节点为空,使用root1的节点
7    if (root2 == null) {
8        return root1;
9    }
10    //利用root1和root2的值构造新节点
11    TreeNode root = new TreeNode(root1.val + root2.val);
12    //递归遍历左右节点
13    root.left = mergeTrees(root1.left, root2.left);
14    root.right = mergeTrees(root1.right, root2.right);
15    return root;
16}

时间复杂度:O(min(m,n)) m、n为分别为两棵二叉树节点,由于合并过程中只要有棵树的节点为空,那么另一个棵树的对应位置节点剩余节点就无需再合并,所以只需要遍历两棵树较小的那棵树节点值即可

空间复杂度:O(min(m,n)


方法二:广度优先遍历

思路:使用三个队列,其中两个分别存储两棵待合并的树的节点,另一个存储新树的节点。

        合并过程如分析,针对每个节点,需要知道该节点是待合并的左节点还是右节点,同时如果待合并的其中一个节点为空,那么直接使用另一个节点即可,且另一个节点剩余子节点也不需要再进行合并了,如果都不为空,那么利用两个节点的值构建新节点,同时将两个节点的左右子节点入队继续合并即可


代码:

 1public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
2    //root1根节点为空,直接root2
3    if (root1 == null) {
4        return root2;
5    }
6    //root2根节点为空,直接root1
7    if (root2 == null) {
8        return root1;
9    }
10    //构建新根节点
11    TreeNode root = new TreeNode(root1.val + root2.val);
12    //广度优先遍历,采用队列存储节点值
13    Queue<TreeNode> queue = new LinkedList<>();
14    Queue<TreeNode> queue1 = new LinkedList<>();
15    Queue<TreeNode> queue2 = new LinkedList<>();
16    //节点入队
17    queue.offer(root);
18    queue1.offer(root1);
19    queue2.offer(root2);
20    while (!queue1.isEmpty() && !queue2.isEmpty()) {
21        //节点出队
22        TreeNode node = queue.poll(), node1 = queue1.poll(), node2 = queue2.poll();
23        //由于二叉树有左右节点,所以需要将root1和root2的左右子节点都标识出来
24        TreeNode left1 = node1.left, left2 = node2.left, right1 = node1.right, right2 = node2.right;
25        if (left1 != null || left2 != null) {
26            //root1和root2左节点都不为空
27            if (left1 != null && left2 != null) {
28                TreeNode left = new TreeNode(left1.val + left2.val);
29                node.left = left;
30                //继续往下遍历
31                queue.offer(left);
32                queue1.offer(left1);
33                queue2.offer(left2);
34            } else if (left1 != null) {
35                //root2左节点为空,那么新树的左节点就是root1的左节点
36                node.left = left1;
37            } else if (left2 != null) {
38                //root1左节点为空,那么新树的左节点就是root2的左节点
39                node.left = left2;
40            }
41        }
42        if (right1 != null || right2 != null) {
43            //root1和root2右节点都不为空
44            if (right1 != null && right2 != null) {
45                TreeNode right = new TreeNode(right1.val + right2.val);
46                node.right = right;
47                //继续往下遍历
48                queue.offer(right);
49                queue1.offer(right1);
50                queue2.offer(right2);
51            } else if (right1 != null) {
52                //root2右节点为空,那么新树的右节点就是root1的右节点
53                node.right = right1;
54            } else {
55                //root1右节点为空,那么新树的右节点就是root2的右节点
56                node.right = right2;
57            }
58        }
59    }
60    return root;
61}

时间复杂度:O(min(m,n)) m、n为分别为两棵二叉树节点,由于合并过程中只要有棵树的节点为空,那么另一个棵树的对应位置节点剩余节点就无需再合并,所以只需要遍历两棵树较小的那棵树节点值即可

空间复杂度:O(min(m,n)



以上仅是个人思路解法,觉得还不错欢迎点赞关注分享


往期精彩推荐




扫描下方二维码,关注公众号,更多精彩等你发现




以上是关于二叉树--合并二叉树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树--合并二叉树

二叉树oj ---->合并二叉树

[二叉树][easy] 平衡二叉树和合并二叉树

二叉树20:合并两个二叉树

二叉树刷题篇 最大二叉树 and 合并二叉树

C++算法最大二叉树,合并二叉树题目详细解读