力扣第617题 合并二叉树 c++ 前中后序 完成 附加迭代版本

题目

617. 合并二叉树

简单

相关标签

树  深度优先搜索  广度优先搜索  二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

力扣第617题 合并二叉树 c++ 前中后序 完成 附加迭代版本_第1张图片

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000] 内
  • -104 <= Node.val <= 104

思路和解题方法

  1. 如果两棵树都为空,返回 null。
  2. 如果其中一棵树为空,返回另一棵树。
  3. 如果两棵树根节点的值相同,将它们的值相加作为新树的根节点,同时将两棵树的左子树和右子树分别递归处理并合并。
  4. 如果两棵树根节点的值不同,将它们的值中不为 null 的一个作为新树的根节点,同时将不为 null 的一个树的左子树和右子树分别递归处理并合并,将另一棵树的左子树和右子树分别作为新树的左子树和右子树。

复杂度

        时间复杂度:

                O(min(m,n))

        该算法,时间复杂度为 O(min(m,n)),其中 m 和 n 分别为两棵二叉树的节点数。这是因为每个节点最多只会被访问一次,因此总共遍历的节点数不会超过两棵树中节点个数的较小值。

        空间复杂度

                O(min(m,n)) 或 O(logm)(或 O(logn),如果两棵树的深度相同)

        空间复杂度,递归调用 mergeTrees 函数时可能会使用 O(min(m,n)) 的栈空间,因为每次递归都只处理其中一棵树的子树,因此栈的最大深度就是较小的子树的最大深度。如果两棵树的深度相同,则使用 O(logm) 或 O(logn) 的栈空间,取决于树的深度。此外,在返回合并后树的时候,需要分配 O(1) 的额外空间来存储新的树节点。

c++ 代码

 ​前序

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2; // 如果 t1 为空,合并之后就应该是 t2
        if (t2 == NULL) return t1; // 如果 t2 为空,合并之后就应该是 t1
        
        t1->val += t2->val;                             // 将 t1 的值加上 t2 的值,作为新树合并后的根节点的值
        
        t1->left = mergeTrees(t1->left, t2->left);      // 合并 t1 和 t2 的左子树,递归调用 mergeTrees 函数
        t1->right = mergeTrees(t1->right, t2->right);   // 合并 t1 和 t2 的右子树,递归调用 mergeTrees 函数
        
        return t1; // 返回合并后的树
    }
};

 ​中序

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
        if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1

        t1->left = mergeTrees(t1->left, t2->left);      // 递归合并t1和t2的左子树
        t1->val += t2->val;                             // 将t1的值加上t2的值,作为新树合并后的根节点的值
        t1->right = mergeTrees(t1->right, t2->right);   // 递归合并t1和t2的右子树
        return t1;                                      // 返回合并后的树
    }
};

后序

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
        if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1

        t1->left = mergeTrees(t1->left, t2->left);      // 递归合并t1和t2的左子树
        t1->right = mergeTrees(t1->right, t2->right);   // 递归合并t1和t2的右子树
        t1->val += t2->val;                             // 将t1的值加上t2的值,作为新树合并后的根节点的值
        return t1;                                      // 返回合并后的树
    }
};

定义新二叉树节点

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
        if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1

        // 创建一个新的节点,不修改原有两个树的结构
        TreeNode* root = new TreeNode(0);
        root->val = t1->val + t2->val;                        // 将t1和t2对应节点的值相加,赋值给新节点的值
        root->left = mergeTrees(t1->left, t2->left);           // 递归合并t1和t2的左子树
        root->right = mergeTrees(t1->right, t2->right);        // 递归合并t1和t2的右子树
        return root;                                          // 返回合并后的树
    }
};

迭代版本

class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
        if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
        
        queue que;
        que.push(t1);
        que.push(t2);
        
        while(!que.empty()) {
            TreeNode* node1 = que.front(); que.pop();
            TreeNode* node2 = que.front(); que.pop();
            // 此时两个节点一定不为空,val相加
            node1->val += node2->val;

            // 如果两棵树左节点都不为空,加入队列
            if (node1->left != NULL && node2->left != NULL) {
                que.push(node1->left);
                que.push(node2->left);
            }
            // 如果两棵树右节点都不为空,加入队列
            if (node1->right != NULL && node2->right != NULL) {
                que.push(node1->right);
                que.push(node2->right);
            }

            // 当t1的左节点为空,t2左节点不为空,就赋值过去
            if (node1->left == NULL && node2->left != NULL) {
                node1->left = node2->left;
            }
            // 当t1的右节点为空,t2右节点不为空,就赋值过去
            if (node1->right == NULL && node2->right != NULL) {
                node1->right = node2->right;
            }
        }
        
        return t1;
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

你可能感兴趣的:(二叉数,leetcode,数据结构,算法,leetcode,c++,深度优先,二叉树,树)