LeetCode合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:
输入:原始二叉树如下图
           
输出:合并后的二叉树如下图
      

注:本文中以如下所示节点表示空节点

 

基于递归的解决思路:

两颗树都从root开始遍历,root合并之后生成新的root节点

接下来,合并两颗树的root.left 然后连接到新root的left上,合并原始root的right节点,连接到新root的right上。

基于上面分析,定义如下递归函数。

//合并给定的两个节点
 public TreeNode mergeTree(TreeNode root1, TreeNode root2) {      

 }

递归终止条件,如果其中一个结点为空,如root2为空,如下,则直接返回root1

基于上面分析,代码如下:

public TreeNode mergeTree(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;

        //到此处说明root1 和 root2都不为空,所以直接生成新的root节点
        TreeNode newNode = new TreeNode(root1.val + root2.val);

        //递归调用mergeTree设置left和right
        newNode.left = mergeTree(root1.left, root2.left);
        newNode.right = mergeTree(root1.right, root2.right);
        return newNode;
    }

基于迭代的解决思路。

题目没有说不可以破坏原树,此处不开辟额外的空间,在原树上进行合并。我们此处假设把树root2合并到root1上。我们可以定义一个队列辅助处理。每一次队列头的两个元素分别来源于两颗二叉树。代表此次要处理的节点,如果给定两个节点,如何合并其子节点?有以下几种方式。

(1)如果root1.left 和 root2.left 都不为空,直接执行root1.left.val = root1.left.val + root2.left.val,同时把root1.left  和 root2.left 入队列即可

 (2)如果root1.right和 root2.right都不为空,直接执行root1.right.val = root1.right.val + root2.right.val,同时把root1.right和 root2.right入队列即可

(3)如果root1.left 为空,则直接把root2.left设置到root1.left上即可

(4)如果root1.right为空,则直接把root2.right设置到root1.right上即可

经过上面分析,代码如下,配合注释很好理解

public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;

        //到此处说明root1和root2都不可能为空,设置root1的value属性,此时root1和root2相当于是已经合并到root1上了
        root1.val = root1.val + root2.val;

        Queue<TreeNode> queue = new LinkedList<>();
        
        //root1 和 root2 分别进入队列
        queue.offer(root1);
        queue.offer(root2);
        while (!queue.isEmpty()) {
            
            //出队两个元素,接下来处理出队的两个元素的子节点
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();

            if (node1.left != null && node2.left != null) {
                node1.left.val = node1.left.val + node2.left.val;
                queue.offer(node1.left);
                queue.offer(node2.left);
            }

            if (node1.right != null && node2.right != null) {
                node1.right.val = node1.right.val + node2.right.val;
                queue.offer(node1.right);
                queue.offer(node2.right);
            }

            //如果node1的left为空,则直接设置node1.left为node2.left
            if (node1.left == null) {
                node1.left = node2.left;
            }

            //如果node1的right为空,则直接设置node1.right为node2.right
            if (node1.right == null) {
                node1.right = node2.right;
            }

        }
        return root1;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值