BM32-合并二叉树

二叉树合并算法

题目

已知两颗二叉树,将它们合并成一颗二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。例如:
两颗二叉树是:
Tree 1

Tree 2

合并后的树为

数据范围:树上节点数量满足0≤n≤500,树上节点的值一定在32位整型范围内。

进阶:空间复杂度 O(1),时间复杂度 O(n)

示例1

输入:{1,3,2,5},{2,1,3,#,4,#,7}

返回值:{3,4,5,5,4,#,7}

示例2

输入:{1},{}

返回值:{1}


思路1:递归

  • step 1:首先判断t1与t2是否为空,若为空则用另一个代替,若都为空,返回的值也是空。
  • step 2:然后依据前序遍历的特点,优先访问根节点,将两个根点的值相加创建到新树中。
  • step 3:两棵树再依次同步进入左子树和右子树。

代码1

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param t1 TreeNode类 
     * @param t2 TreeNode类 
     * @return TreeNode类
     */
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        if(t1 == null) {
            return t2;
        }
        if(t2 == null) {
            return t1;
        }
        TreeNode head = new TreeNode(t1.val + t2.val);
        head.left = mergeTrees(t1.left, t2.left);
        head.right = mergeTrees(t1.right, t2.right);
        return head;
    }
}

思路2:非递归层次遍历

非递归的层次遍历,也可以实现两棵树同步遍历节点相加,重点是两棵树从根节点开始每个节点是同步走的,因此可以使用队列辅助两个二叉树分别同时层次遍历。

具体做法:

  • step 1:首先判断t1与t2是否为空,若为空则用另一个代替,若都为空,返回的值也是空。
  • step 2:使用三个辅助队列,第一个队列q用于暂存合并后的二叉树的层次遍历节点,第二个队列q1用于暂存t1的层次遍历节点,第三个队列q2用于暂存t2的层次遍历节点。
  • step 3:两棵树同步层次遍历,先将根节点加入队列中,同时根节点优先合并。
  • step 4:每次从队列分别弹出一个元素,判断分别二者的左右子节点是否存在,若是都存在,则相加合并,若是只存在一个则连接该存在的节点,若是都不存在则连接null。

代码2

import java.util.*;

public class Solution {
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        //若只有一个节点返回另一个,两个都为null自然返回null
        if(t1 == null) {
            return t2;
        }
        if(t2 == null) {
            return t1;
        }

        //合并根节点
        TreeNode head = new TreeNode(t1.val + t2.val); 
        //连接后的树的层次遍历节点
        Queue<TreeNode> q = new LinkedList<TreeNode>(); 
        //分别存两棵树的层次遍历节点
        Queue<TreeNode> q1 = new LinkedList<TreeNode>(); 
        Queue<TreeNode> q2 = new LinkedList<TreeNode>();
        q.offer(head);
        q1.offer(t1);  
        q2.offer(t2);

        while (!q1.isEmpty() && !q2.isEmpty()) {
            TreeNode node = q.poll();
            TreeNode node1 = q1.poll(); 
            TreeNode node2 = q2.poll();
            TreeNode left1 = node1.left;
            TreeNode left2 = node2.left;
            TreeNode right1 = node1.right;
            TreeNode right2 = node2.right;

            if(left1 != null || left2 != null) { 
                //两个左节点都存在
                if(left1 != null && left2 != null) { 
                    TreeNode left = new TreeNode(left1.val + left2.val);
                    node.left = left; 
                    //新节点入队列
                    q.offer(left);  
                    q1.offer(left1);
                    q2.offer(left2);
                //只连接一个节点
                } else if(left1 != null) {
                    node.left = left1;
                } else {
                    node.left = left2;
                }
            }

            if(right1 != null || right2 != null) {
                //两个右节点都存在
                if(right1 != null && right2 != null) { 
                    TreeNode right = new TreeNode(right1.val + right2.val);
                    node.right = right;
                    //新节点入队列
                    q.offer(right); 
                    q1.offer(right1);
                    q2.offer(right2);
                //只连接一个节点
                } else if(right1 != null) {
                    node.right = right1;
                } else {
                    node.right = right2;
                }
            }
        }
        return head;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值