Day16 | 112路径总和&106从中序与后序遍历序列构造二叉树&654最大二叉树&617合并二叉树

64 阅读3分钟

路径总和 LeetCode 112

题目链接:[LeetCode 112 - 简单]

思路

首先想到的就是使用递归

递归结束的条件:确认当前节点为叶子节点,而其targetSum为当前叶子节点的值 root.left==null && root.right==null && targetSum == root.val

递归:

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root==null) return false;
        if(root.left==null && root.right==null && targetSum == root.val){
            return true;
        }
        boolean left = hasPathSum(root.left,targetSum-root.val);
        boolean right = hasPathSum(root.right,targetSum-root.val);
        return left||right;
    }
}

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

题目链接:[LeetCode 106 - 中等]

思路

首先得确定左闭右开还是左闭右闭

我写的代码为左闭右闭

使用一个私有的函数来辅助建立二叉树

首先得明确的是:中序遍历:左中右 后序遍历:左右中 通过后序遍历可以确定根节点。

具体操作: ①创建一个hashmap,将中序遍历的数值和所在数组中的index通过键值对的方式存储:用来在后序遍历确定根节点的数值时,找到其在中序遍历中的位次 ②在中序遍历中,根节点左侧为其左子树,根节点右侧为其右子树。 ③可以在中序遍历中,确定其左子树的个数,从而找到其左子树在后序遍历中的子数组 ④通过递归的方式可以构造二叉树

递归:

class Solution {
    HashMap<Integer,Integer> hashmap = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i=0;i<inorder.length;i++){
            hashmap.put(inorder[i],i);
        }
        return dfs(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
    }
    private TreeNode dfs(int[] inorder,int inBegin,int inEnd,int[] postorder,int postBegin,int postEnd){
        if(inBegin>inEnd || postBegin>postEnd){
            return null;
        }
        int rootIndex = hashmap.get(postorder[postEnd]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenOfLeft = rootIndex - inBegin;
        root.left = dfs(inorder,inBegin,rootIndex-1,postorder,postBegin,postBegin+lenOfLeft-1);
        root.right = dfs(inorder,rootIndex+1,inEnd,postorder,postBegin+lenOfLeft,postEnd-1);
        return root;
    }
}

最大二叉树 LeetCode 654

题目链接:[LeetCode 654 - 中等]

思路

思路和#106类似,并且较106更加简单

细节有所不同,主要是在数组中逐步找到左右子树中的最大值,然后将其数组左侧的设置为左子树,右侧的设置为右子树

递归:

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        if(nums.length==0)return null;
        return constructHelper(nums,0,nums.length-1);
    }
    private TreeNode constructHelper(int[] nums,int begin,int end){
        if(begin>end){
            return null;
        }
        int index=begin;
        int max=nums[begin];
        for(int i=begin+1;i<=end;i++){
            if(nums[i]>=max){
                index=i;
                max = nums[i];
            }
        }
        TreeNode root = new TreeNode(nums[index]);
        root.left = constructHelper(nums,begin,index-1);
        root.right = constructHelper(nums,index+1,end);
        return root;
    }
}

合并二叉树 LeetCode 617

题目链接:[LeetCode 617 - 简单]

思路

首先想到的就是使用递归

分别将其分为四种可能:①root1为空root2为空②root1为空root2非空③root1非空root2为空④root1和root2都非空

但是如果按照上述四种情况写的话代码存在冗余,因此分为三种情况:①root1为空 -> 取root2(其包含了root1为空root2为空这种情况)②root1非空,root2为空 ->取root1③root1和root2都非空 -> 将root2的值加到root1上,并且对root1的左子树和右子树都按照之前的规定递归,最终返回root1的根节点

递归:

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

        root1.val += root2.val;
        root1.left = mergeTrees(root1.left,root2.left);
        root1.right = mergeTrees(root1.right,root2.right);
        return root1;
    }
}