美文网首页
LeetCode—— 合并二叉树

LeetCode—— 合并二叉树

作者: Minority | 来源:发表于2020-02-09 17:14 被阅读0次

题目描述

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

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 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;
四、各语言及算法时间复杂度

相关文章

网友评论

      本文标题:LeetCode—— 合并二叉树

      本文链接:https://www.haomeiwen.com/subject/kqvgxhtx.html