备战实习记录之【树与二叉树篇】5——二叉树的常见问题(递归+迭代 应用)

5 二叉树的常见问题(递归+迭代 应用)

5.1 判断二叉树是否对称(101. 对称二叉树)

5.1.1 解法一:迭代解法

5.1.2 解法二:递归解法

5.2 求树的最大深度

5.2.1 104. 二叉树的最大深度

5.2.2 559. N 叉树的最大深度

5.3 求树的最小深度

5.3.1 111. 二叉树的最小深度

5.4 判断树是否平衡

5.4.1 110. 平衡二叉树 

5.5 257. 二叉树的所有路径

5.6 404. 左叶子之和

5.7 513. 找树左下角的值

5.8 递归遍历路径

5.8.1112. 路径总和

5.8.2 113. 路径总和 II

5.9 构建二叉树(重要)

5.9.1 106. 从中序与后序遍历序列构造二叉树

5.9.2 105. 从前序与中序遍历序列构造二叉树

5.9.3 654. 最大二叉树

5.10 合并两个二叉树

5.10.1 617. 合并二叉树


5 二叉树的常见问题(递归+迭代 应用)

5.1 判断二叉树是否对称(101. 对称二叉树

5.1.1 解法一:迭代解法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root.left);
        queue.offer(root.right);
        while(!queue.isEmpty()){
            TreeNode leftnode = queue.poll();
            TreeNode rightnode = queue.poll();
            
            if(leftnode==null&&rightnode==null){
                continue;
            }
            if(leftnode==null||rightnode==null||(leftnode.val!=rightnode.val)){
                return false;
            }
            queue.offer(leftnode.left);
            queue.offer(rightnode.right);
            queue.offer(leftnode.right);
            queue.offer(rightnode.left);
        }
        return true;
    }
}

5.1.2 解法二:递归解法

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        return compare(root.left,root.right);
    }
    public boolean compare(TreeNode left,TreeNode right){
        if(right==null&&left!=null) return false;
        else if(left==null&&right!=null) return false;
        else if(left==null&&right==null) return true;
        else if(left.val!=right.val) return false;

        boolean res1 = compare(left.left,right.right);
        boolean res2 = compare(left.right,right.left);
        return res1&&res2;

    }   
}

5.2 求树的最大深度

5.2.1 104. 二叉树的最大深度

JAVA解法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        int res = 0;
        if(root!=null) queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                TreeNode node = queue.poll();
                if(i==size-1) res+=1;
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
        }
        return res;
    }
}

递归解法:

class Solution {
    public int maxDepth(TreeNode root) {
        return getDepth(root);
    }
    public int getDepth(TreeNode node){
        if(node==null) return 0;
        int leftdep = getDepth(node.left);
        int rightdep = getDepth(node.right);
        int res = 1+Math.max(leftdep,rightdep);
        return res;
    }
}

5.2.2 559. N 叉树的最大深度

JAVA解法:

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public int maxDepth(Node root) {
        Queue<Node> queue = new LinkedList<>();
        int res = 0;
        if(root!=null) queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            res++;
            for(int i=0;i<size;i++){
                Node node = queue.poll();
                for(Node ch : node.children){
                    queue.offer(ch);
                }
            }
        }
        return res;
    }
}

递归解法:

class Solution {
    public int maxDepth(Node root) {
        if(root==null) return 0;
        int res = 0;
        for(Node ch:root.children){
            res = Math.max(res,maxDepth(ch));
        }
        return res+1;
    }
}

5.3 求树的最小深度

5.3.1 111. 二叉树的最小深度

Java解法:

解法一:层次遍历

class Solution {
    public int minDepth(TreeNode root) {
        if(root == null) return 0;
        Queue<TreeNode> queue = new LinkedList<>();
        int mindep = 0;
        queue.offer(root);
        while(!queue.isEmpty()){
            int size = queue.size();
            mindep++;
            int flag = 0;
            for(int i=0;i<size;i++){
                TreeNode node = queue.poll();
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
                if(node.left==null&&node.right==null){
                    flag=1;
                    break;
                }
                
            }
            if(flag==1) break;
        }
        return mindep;

    }
}

解法二:递归求解

class Solution {
    public int minDepth(TreeNode root) {
        if(root==null) return 0;
        int res = 0;
        int leftdep = minDepth(root.left);
        int rightdep = minDepth(root.right);
        if(root.left==null&&root.right!=null) return 1+rightdep;
        else if(root.left!=null && root.right==null) return 1+leftdep;
        else return 1+Math.min(leftdep,rightdep);
    }
}

5.4 判断树是否平衡

5.4.1 110. 平衡二叉树 

递归三步曲分析:

  1. 明确递归函数的参数和返回值

参数的话为传入的节点指针,就没有其他参数需要传递了,返回值要返回传入节点为根节点树的深度。

那么如何标记左右子树是否差值大于1呢。

如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。

所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。

代码如下:

// -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
int getDepth(TreeNode* node)
  1. 明确终止条件

递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的高度为0

代码如下:

if (node == NULL) {
    return 0;
}
  1. 明确单层递归的逻辑

如何判断当前传入节点为根节点的二叉树是否是平衡二叉树呢,当然是左子树高度和右子树高度相差。

分别求出左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则则返回-1,表示已经不是二叉树了。

代码如下:

int leftDepth = depth(node->left); // 左
if (leftDepth == -1) return -1;     
int rightDepth = depth(node->right); // 右
if (rightDepth == -1) return -1;

int result;
if (abs(leftDepth - rightDepth) > 1) {  // 中
    result = -1;
} else {
    result = 1 + max(leftDepth, rightDepth); // 以当前节点为根节点的最大高度
}

return result;

代码精简之后如下:

int leftDepth = getDepth(node->left);
if (leftDepth == -1) return -1;     
int rightDepth = getDepth(node->right);
if (rightDepth == -1) return -1;
return abs(leftDepth - rightDepth) > 1 ? -1 : 1 + max(leftDepth, rightDepth);

此时递归的函数就已经写出来了,这个递归的函数传入节点指针,返回以该节点为根节点的二叉树的高度,如果不是二叉平衡树,则返回-1。

来自 【代码随想录】

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        int res = getDepth(root);
        if(res == -1) return false;
        else return true;
    }
    public int getDepth(TreeNode node){
        if(node==null) return 0;
        int leftdepth = getDepth(node.left);
        if(leftdepth == -1) return -1;
        int rightdepth = getDepth(node.right);
        if(rightdepth == -1) return -1;
        int res = 0;
        if(Math.abs(leftdepth-rightdepth)>1) return -1;
        else{
            res = 1+Math.max(leftdepth,rightdepth);
        }
        return res;
    }
}

5.5 257. 二叉树的所有路径

使用递归解题。注意以下几点:

一是终止条件为:当 cur不为空,其左右孩子都为空的时候,就找到叶子节点。就开始加入当前路径,并开始回溯。

为什么没有判断cur是否为空呢,因为下面的逻辑可以控制空节点不入循环。

再来看一下终止处理的逻辑。

这里使用List结构path来记录路径,所以要把List结构的path转为string格式,在把这个string 放进 res里。

二是前序遍历——确定单层递归逻辑

因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。

path.add(node.val);

然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。

所以递归前要加上判断语句,下面要递归的节点是否为空.

三是注意加回溯语句。

递归与回溯是一体的。因此决不能只回溯一次。回溯需要和左右子树的递归语句写在一起。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        if(root==null) return res;
        getData(root,res,path);
        return res;

    }
    public void getData(TreeNode node,List<String> res,List<Integer> path){
        path.add(node.val);
        if(node.left==null && node.right == null){
            String tmp = "";
            for(int i=0;i<path.size()-1;i++){
                tmp+=path.get(i);
                tmp+="->";
            }
            tmp+=path.get(path.size()-1);
            res.add(tmp);
            return;
        }
        if(node.left!=null){
            getData(node.left,res,path);
            path.remove(path.size()-1);
        }
        if(node.right!=null){
            getData(node.right,res,path);
            path.remove(path.size()-1);
        }
    }
}

5.6 404. 左叶子之和

「判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。」

如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:

if(node.left!=null && node.left.left==null && node.left.right==null){
    左叶子节点处理逻辑
}

迭代法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        Stack<TreeNode> st = new Stack<>();
        if(root!=null) st.push(root);
        int res = 0;
        while(!st.empty()){
            TreeNode node = st.pop();
            if(node.left!=null && node.left.left==null && node.left.right==null){
                res+=node.left.val;
            }
            if(node.left!=null) st.push(node.left);
            if(node.right!=null) st.push(node.right);
        }
        return res;
    }
}

递归法:

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if(root==null) return 0;
        int leftsum = sumOfLeftLeaves(root.left);
        int rightsum = sumOfLeftLeaves(root.right);
        int midsum = 0;
        if(root.left!=null && root.left.left==null && root.left.right==null){
            midsum+=root.left.val;
        }
        return midsum+leftsum+rightsum;
    }
}

5.7 513. 找树左下角的值

首先要是最后一行,然后是最左边的值。

本题使用层序遍历再合适不过了,只需要记录最后一行第一个节点的数值就可以了。

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(root!=null) queue.offer(root);
        int res = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                TreeNode node = queue.poll();
                if(i==0) res = node.val;
                if(node.left!=null) queue.offer(node.left);
                if(node.right!=null) queue.offer(node.right);
            }
        }
        return res;

    }
}

5.8 递归遍历路径

递归什么时候需要返回值什么时候不需要?

「如果需要搜索整颗二叉树,那么递归函数就不要返回值,如果要搜索其中一条符合条件的路径,递归函数就需要返回值,因为遇到符合条件的路径了就要及时返回。」

5.8.1112. 路径总和

1.这道题遍历时,并不要遍历整棵树,所以递归函数需要返回值,可以用bool类型表示。

2.如何统计这一条路径的和呢?

不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。

如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。

如果遍历到了叶子节点,count不为0,就是没找到。

3.确定单层递归的逻辑

因为终止条件是判断叶子节点,所以递归的过程中就不要让空节点进入递归了。

递归函数是有返回值的,如果递归函数返回true,说明找到了合适的路径,应该立刻返回。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null) return false;
        return transfer(root,targetSum-root.val);
    }
    public boolean transfer(TreeNode node,int count){
        if(node.left==null && node.right==null && count==0) return true;
        if(node.left==null && node.right==null) return false;
        if(node.left!=null){
            count-=node.left.val;
            if(transfer(node.left,count)) return true;
            count+=node.left.val;
        }
        if(node.right!=null){
            count-=node.right.val;
            if(transfer(node.right,count)) return true;
            count+=node.right.val;
        }
        return false;
    }
}

5.8.2 113. 路径总和 II

下面代码中踩了一个坑:

一开始在递归中满足条件时,将path加入到res中,写的是:res.add(path);

但是导致res集合始终是空的。

改成:res.add(new ArrayList<>(path));  之后正常运行得出结果。

这里主要是因为:path是引用类型,直接加的话,从始至终加入的都是同一个path,值没有改变。

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        if(root==null) return res;
        path.add(root.val);
        getPath(root,targetSum-root.val);
        return res;

    }
    public void getPath(TreeNode node,int count){
        if(node.left==null && node.right==null && count==0) {
            res.add(new ArrayList<>(path));
            return;
        }
        if(node.left==null && node.right==null) return;
        if(node.left!=null){
            path.add(node.left.val);
            count-=node.left.val;
            getPath(node.left,count);
            count+=node.left.val;
            path.remove(path.size()-1);
        }
        if(node.right!=null){
            path.add(node.right.val);
            count-=node.right.val;
            getPath(node.right,count);
            count+=node.right.val;
            path.remove(path.size()-1);
        }
        return;
    }
}

改进简洁写法:

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        getPath(root,targetSum);
        return res;
    }
    public void getPath(TreeNode node,int count){
        if(node==null) return;
        path.add(node.val);
        count-=node.val;
        if(node.left==null && node.right==null && count==0){
            res.add(new ArrayList(path));
        }
        getPath(node.left,count);
        getPath(node.right,count);
        path.remove(path.size()-1);
        return;
    }
}

5.9 构建二叉树(重要)

5.9.1 106. 从中序与后序遍历序列构造二叉树

主要思路:以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来在切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

下面是根据上面的思路为基础完成的代码,不是很简洁但是很清晰:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode root = null;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(inorder.length==0 && postorder.length==0) return null;
        return helper(inorder,postorder);

    }
    public TreeNode helper(int[] inorder,int [] postorder){
        if(postorder.length==0) return null;

        int rootval = postorder[postorder.length-1];
        TreeNode root = new TreeNode(rootval);

        if(postorder.length==1) return root;

        int ind ;
        for(ind = 0;ind<inorder.length;ind++){
            if(inorder[ind]==rootval) break;
        }
        //切割中序数组
        int n1 = ind;
        int n2 = ind;
        int [] leftin = new int [ind];
        int [] rightin = new int [inorder.length-ind-1];
        for(int i=0;i<ind;i++){
            leftin[i] = inorder[i];
        }
        n1++;
        for(int j=0;j<inorder.length-ind-1;j++){
            rightin[j] = inorder[n1++];
        }

        //切割后序数组
        int [] leftpost = new int [ind];
        int [] rightpost = new int [inorder.length-ind-1];
        for(int i=0;i<ind;i++){
            leftpost[i] = postorder[i];
        }
        for(int j=0;j<inorder.length-ind-1;j++){
            rightpost[j] = postorder[n2++];
        }
        

        //递归
        root.left = helper(leftin,leftpost);
        root.right = helper(rightin,rightpost);
        return root;

    }
}

简洁代码版本:

在处理之前,使用HashMap处理中序遍历结果的信息。之后就可以直接访问键值来定位元素。不用重复赋值给数组。

即变化的只有下标,元素值没有变化。

class Solution {
    HashMap<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i=0;i<inorder.length;i++){
            map.put(inorder[i], i);
        }
        return helper(inorder, 0, inorder.length-1, postorder, 0, postorder.length-1);
    }
    public TreeNode helper(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight){
        //终止条件
        if(inLeft > inRight || postLeft > postRight) return null;
        //从后序遍历中拿到根节点
        int root = postorder[postRight];
        //从中序取出根节点的索引
        int index = map.get(root);
        //构建根节点
        TreeNode tree = new TreeNode(root);

        tree.left = helper(inorder, inLeft, index-1, postorder, postLeft, postRight-inRight+index-1);
        tree.right = helper(inorder, index+1, inRight, postorder, postRight-inRight+index, postRight-1);
        return tree;
    }
}

5.9.2 105. 从前序与中序遍历序列构造二叉树

注意:

不管是后序还是前序,都必须根据中序左子树长度去定义自己的左子树长度。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    HashMap<Integer,Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for(int i=0;i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        return helper(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    public TreeNode helper(int [] preorder,int prest,int preend,int [] inorder,int inst,int inend){
        if(inst>inend || prest>preend) return null;

        int rootval = preorder[prest];
        int ind = map.get(rootval);

        TreeNode root = new TreeNode(rootval);
        int leftnum = ind-inst;
        root.left = helper(preorder,prest+1,prest+leftnum,inorder,inst,ind-1);
        root.right = helper(preorder,prest+leftnum+1,preend,inorder,ind+1,inend);
        return root;
    }
}

5.9.3 654. 最大二叉树

单层递归的逻辑

  1. 先要找到数组中最大的值和对应的下表, 最大的值构造根节点,下标用来下一步分割数组。

  2. 最大值所在的下表左区间 构造左子树 这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。

  3. 最大值所在的下表右区间 构造右子树 判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        if(nums.length==1){
            return new TreeNode(nums[0]);
        } else if(nums.length==0) return null;
        
        int maxval = 0;
        int maxind = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]>maxval){
                maxval = nums[i];
                maxind = i;
            }
        }

        TreeNode root = new TreeNode(maxval);
        if(maxind>0){
            root.left = constructMaximumBinaryTree(Arrays.copyOfRange(nums,0,maxind));
        }
        if(maxind<nums.length-1){
            root.right = constructMaximumBinaryTree(Arrays.copyOfRange(nums,maxind+1,nums.length));
        }
        return root;

    }
}

5.10 合并两个二叉树

5.10.1 617. 合并二叉树

1.确定递归函数的参数和返回值:

首先那么要合入两个二叉树,那么参数至少是要传入两个二叉树的根节点,返回值就是合并之后二叉树的根节点。

2.确定终止条件:

因为是传入了两个树,那么就有两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL)。

反过来如果t2 == NULL,那么两个数合并就是t1(如果t1也为NULL也无所谓,合并之后就是NULL)。

3.确定单层递归的逻辑:

单层递归的逻辑就比较好写了,这里我们用重复利用一下t1这个树,t1就是合并之后树的根节点(就是修改了原来树的结构)。

那么单层递归中,就要把两棵树的元素加到一起。

接下来t1 的左子树是:合并 t1左子树 t2左子树之后的左子树。

t1 的右子树:是 合并 t1右子树 t2右子树之后的右子树。

最终t1就是合并之后的根节点。

前序遍历解法:

/**
 * 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) {
        if(t1==null) return t2;
        if(t2==null) return t1;
        t1.val +=t2.val;
        t1.left = mergeTrees(t1.left,t2.left);
        t1.right = mergeTrees(t1.right,t2.right);
        return t1;
    }
}

迭代法解法:

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        Queue<TreeNode> queue = new LinkedList<>();
        if(t1==null) return t2;
        if(t2==null) return t1;
        queue.offer(t1);
        queue.offer(t2);
        while(!queue.isEmpty()){
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
            node1.val+=node2.val;
            if(node1.left!=null && node2.left!=null){
                queue.offer(node1.left);
                queue.offer(node2.left);
            }
            if(node1.right!=null && node2.right!=null){
                queue.offer(node1.right);
                queue.offer(node2.right);
            }
            if(node1.left==null && node2.left!=null){
                node1.left = node2.left;
            }
            if(node1.right==null && node2.right!=null){
                node1.right = node2.right;
            }
        }
        return t1;
    }
}

猜你喜欢

转载自blog.csdn.net/paranior/article/details/115307342
今日推荐