题目描述
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。
你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。
示例 1:
输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/ \
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。
一、CPP
1. 递归法:
解题思路:对这两棵树同时进行前序遍历,并将r1和r2对应的节点进行合并到r1上。在遍历时,如果两棵树的当前节点均不为空,我们就将它们的值进行相加,并对它们的左孩子和右孩子进行递归合并;如果其中有一棵树为空,那么我们返回另一颗树作为结果;如果两棵树均为空,此时返回任意一棵树均可(因为都是空)。
时间复杂度:O(N),其中 N是两棵树中节点个数的较小值。
空间复杂度:O(N),在最坏情况下,会递归 N 层,需要O(N) 的栈空间。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
//前序遍历:根左右
if(t1 == NULL || t2== NULL){
return t1 == NULL ? t2 : t1;
}
t1->val = t1->val + t2->val;
t1->left = mergeTrees(t1->left,t2->left);
t1->right = mergeTrees(t1->right,t2->right);
return t1;
}
};
- 注意:C++指针类型的结构体需要使用“
->
”,而不能使用“.
”。
2. 迭代法(层次遍历一):
解题思路:迭代实现用的是广度优先算法,广度优先就需要额外的数据结构来辅助了,可以借助栈或者队列来完成。下面使用队列来完成。只要两颗树的左节点都不为null,就把将他们放入队列中;同理只要两棵树的右节点都不为null了,也将他们放入队列中。然后我们不断的从队列中取出节点,把他们相加。如果出现 树1的left节点为null,树2的left不为null,直接将树2的left赋给树1就可以了;同理如果树1的right节点为null,树2的不为null,将树2的right节点赋给树1。
时间复杂度:O(N),其中 N是两棵树中节点个数的较小值。
空间复杂度:O(N),最坏的情况,对于满二叉树时,要保存所有的叶子节点,即N/2个节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if(t1 == NULL || t2 == NULL){
return t1 == NULL ? t2 : t1;
}
queue<TreeNode*> myqueue;
myqueue.push(t1);
myqueue.push(t2);
//注意是TreeNode的指针类型,在node1基础上进行修改
TreeNode *node1,*node2;
while(!myqueue.empty()){
//顺序遍历:根
node1 = myqueue.front();
myqueue.pop();
node2 = myqueue.front();
myqueue.pop();
node1->val = node1->val + node2->val;
//左子树
if(node1->left && node2->left){
myqueue.push(node1->left);
myqueue.push(node2->left);
}
else if(node1->left == NULL){
node1->left = node2->left;
}
//右子树
if(node1->right && node2->right){
myqueue.push(node1->right);
myqueue.push(node2->right);
}
else if(node1->right == NULL){
node1->right = node2->right;
}
}
return t1;
}
};
3. 迭代法(层次遍历二):
解题思路:每次从两个树中各取一个节点(记为node1, node2)入队;出队时将两个节点值相加,并判断node1和node2的左子树是否为空,若两个左子树都不空,直接入队;若有一个为空,新建一个val为0的节点,然后入队;若两个的左子树都为空,pass。右子树的判断同理。
时间复杂度:O(N),其中 N是两棵树中节点个数的较小值。
空间复杂度:O(N)。运行超出了内存限制。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if(t1 == NULL || t2 == NULL){
return t1 == NULL ? t2 : t1;
}
queue<TreeNode*> myqueue;
TreeNode *node1, *node2;
myqueue.push(t1);
myqueue.push(t2);
while(!myqueue.empty()){
//层序遍历
node1 = myqueue.front();
myqueue.pop();
node2 = myqueue.front();
myqueue.pop();
//对应相加,遇NULL补0
node1->val += node2->val;
//左节点
if(node1->left == NULL){
node1->left = new TreeNode(0);
}
if(node2->left == NULL){
node2->left = new TreeNode(0);
}
myqueue.push(node1->left);
myqueue.push(node2->left);
//右节点
if(node1->right == NULL){
node1->right = new TreeNode(0);
}
if(node2->right == NULL){
node2->right = new TreeNode(0);
}
myqueue.push(node1->right);
myqueue.push(node2->right);
}
return t1;
}
};
同样的方法和思路,用下面这种方式写就没事......不解。
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2)
{
if(!t1)
return t2;
if(!t2)
return t1;
queue<TreeNode*> q;
q.push(t1);
q.push(t2);
TreeNode *node1, *node2;
while(!q.empty()){
node1 = q.front();
q.pop();
node2 = q.front();
q.pop();
node1->val += node2->val; //val相加
if(node1->left || node2->left){ //左子树判断
if(!node1->left)
node1->left = new TreeNode(0);
if(!node2->left)
node2->left = new TreeNode(0);
q.push(node1->left);
q.push(node2->left);
}
if(node1->right || node2->right){ //右子树判断
if(!node1->right)
node1->right = new TreeNode(0);
if(!node2->right)
node2->right = new TreeNode(0);
q.push(node1->right);
q.push(node2->right);
}
}
return t1;
}
};
二、Java(递归发)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
//java中的null是小写
if(t1 == null || t2 == null){
return t1 == null ? t2 : t1;
}
t1.val += t2.val;
t1.left = mergeTrees(t1.left,t2.left);
t1.right = mergeTrees(t1.right,t2.right);
return t1;
}
}
三、Python(递归法)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def mergeTrees(self, t1, t2):
"""
:type t1: TreeNode
:type t2: TreeNode
:rtype: TreeNode
"""
if t1 is None or t2 is None:
if t1:
return t1
else:
return t2
t1.val += t2.val
t1.left = self.mergeTrees(t1.left,t2.left)
t1.right = self.mergeTrees(t1.right,t2.right)
return t1;
网友评论