题目描述
已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:
两颗二叉树是:
Tree 1
1
/ \
3 2
/
5
Tree 2
2
/
1 3
\
4 7
合并后的树为
3
/
4 5
/ \
5 4 7
方法一:队列的思想
求解思路
对于本题要合并二叉树,我们可以借用一个队列,利用队列将两个二叉树根节点存储,然后队列弹出根节点相加,接着如果两个树的左节点均不为空,则将其放入队列,相应的如果右子树的结点均不为空,则同样操作。最后我们不断将子树放入队列,再从队列中取出节点,直到队列为空,这样最终即可得到合并后的二叉树。
解题代码
import java.util.*; public class Solution { public TreeNode mergeTrees (TreeNode t1, TreeNode t2) { if(t1==null || t2==null)//存在一个二叉树为空,则返回另一个二叉树 { return t1==null? t2 : t1; } LinkedList<TreeNode> mylinkedList = new LinkedList<>(); // 声明一个队列存储二叉树 mylinkedList.add(t1); mylinkedList.add(t2); while (!mylinkedList.isEmpty()) { TreeNode n1 = mylinkedList.poll(); // 弹出一个元素 TreeNode n2 = mylinkedList.poll(); n1.val = n1.val + n2.val; if (n1.left != null && n2.left != null) // 两个数的左子树都不为空则将其放到列表中 { mylinkedList.add(n1.left); // 添加子树 mylinkedList.add(n2.left); } else if (n1.left == null) // 如果t1的左子树为空,将t2的左子树直接赋予t1 { n1.left = n2.left; // 将n2的左子树赋值给n1 } if (n1.right != null && n2.right != null) // 两个数的右子树都不为空则将其放到列表中 { mylinkedList.add(n1.right); // 同上面的思路 mylinkedList.add(n2.right); } else if (n1.right == null) // 如果t1的右子树为空,将t2的右子树直接赋予t1 { n1.right = n2.right; } } return t1; // 返回最终的二叉树 } }
复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:使用队列,引入了额外的内存地址空间,因此空间复杂度为
方法二:优化方法--递归的思想
求解思路
我们对第一种方法进行优化,使用先序遍历的方法对二叉树进行遍历,在遍历的过程中对两个二叉树的相应节点进行相加。如果一个树的节点为空,另一个树的节点不为空,则将另一个树节点的值赋给第一个树。按上面的描述进行递归,最终求得合并之后的二叉树。
解题代码
import java.util.*; public class Solution { public TreeNode mergeTrees (TreeNode t1, TreeNode t2) { //递归方法,简洁明了! 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; // 递归终止条件 } }
复杂度分析
时间复杂度:其时间取决于递归的层数,和树的深度有关,因此时间复杂度为,其中N为两棵树结点数的较小值。
空间复杂度:没有引入新的内存地址空间,因此空间复杂度为