合并二叉树
问题描述:已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将节点值加起来,否则空的位置就由另一个树的节点来代替。例如:
两颗二叉树是:Tree 1
1
/ \
3 2
/
5
Tree 2
2
/ \
1 3
\ \
4 7
合并后的树为
3
/ \
4 5
/ \ \
5 4 7
示例1
输入:{1,3,2,5},{2,1,3,#,4,#,7}
返回值:{3,4,5,5,4,#,7}
方法一
思路分析
对二叉树的遍历还可通过层序遍历,即在层序遍历的过程中合并二叉树,此时需要使用一个辅助的数据结构,此处使用了队列,首先利用队列将两个二叉树根节点存储,然后队列弹出根节点相加,如果两个树的左节点均不为空,增将其放入队列,相应的如果两个树的右节点均不为空,增将其放入队列中,如果t1二叉树的左节点为空,t2左节点不为空,直接将t2的左节点赋予t1,同理右节点也如此,由此我们不断将子树放入队列,再从队列中取出节点,直到队列为空。层序遍历的核心思想是一层一层进行遍历。
动图详解
核心代码
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
// write code here
if(t1==null || t2==null)//存在一个二叉树为空,则返回另一个二叉树
{
return t1==null? t2 : t1;
}
LinkedList<TreeNode> linkedList = new LinkedList<>();//声明一个队列用于存储二叉树
linkedList.add(t1);
linkedList.add(t2);
while (!linkedList.isEmpty()){
TreeNode n1 = linkedList.poll();//弹出一个元素。根据不同的数据结构,结果也相应不同,此处为二叉树
TreeNode n2 = linkedList.poll();
n1.val = n1.val + n2.val;
if (n1.left != null && n2.left != null)//两个数的左子树都不为空则将其放到列表中
{
linkedList.add(n1.left);
linkedList.add(n2.left);
}
else if (n1.left == null)//如果t1的左子树为空,将t2的左子树直接赋予t1
{
n1.left = n2.left;
}
if (n1.right != null && n2.right != null)//两个数的右子树都不为空则将其放到列表中
{
linkedList.add(n1.right);
linkedList.add(n2.right);
}
else if (n1.right == null)////如果t1的右子树为空,将t2的右子树直接赋予t1
{
n1.right = n2.right;
}
}
return t1;
}
} 复杂度分析
- 时间复杂度:层序遍历时间复杂度为$O(N)$
- 空间复杂度:借助了一个辅助队列来存储二叉树节点,因此空间复杂度为$O(N)$
方法二
思路分析
我们已经知道对二叉树的访问有前序、中序、后序遍历三种基本的办法,那么我们可以想到可以使用前序遍历的方法对二叉树进行遍历,在遍历的过程中对两个二叉树的相应节点进行相加,这个过程可以用到递归方法,即树t1节点并且树t2的节点不为空时,合并两个节点的数值,递归合并两个树的左节点,递归合并两个树的右节点,如果树t1节点或者树t2的节点为空时,将树t2的节点赋值给t1,当两个数的节点都为空时,遍历完成,递归也就完成,此时t1即为合并后的二叉树。
动图详解
先进行根节点的合并,然后对左子树进行递归合并,之后对右子树递归合并,当两个树的节点均为空时,递归条件结束
JAVA 核心代码
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
// write code here
if(t1 != null && t2 !=null)//递归中止的条件,树t1节点为空并且树t2的节点为空
{
t1.val += t2.val;//将两个树的结点数值相加
t1.left = mergeTrees(t1.left, t2.left);//递归合并两个树的左节点
t1.right = mergeTrees(t1.right, t2.right);//递归合并两个数的右节点
}
return t1 == null? t2 : t1;
}
} 复杂度分析
- 时间复杂度:递归的时间复杂度为递归的次数*每次递归中的操作次数,每次递归中的操作为一个加法操作,递归的次数为较小二叉树的节点数,因此时间复杂度为$O(min(t1,t2))$
- 空间复杂度:取决于递归调用的层数,递归调用的层数不会大于最小二叉树的高度,即空间复杂度$O(min(h1,h2))$,其中h1,h2分别为二叉树t1,t2的高度,最坏情况下二叉树的高度等于节点数

京公网安备 11010502036488号