刷题日记16 | 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树

52 阅读2分钟

刷题日记16

今天依然是二叉树,巩固一下带回溯的递归法,还有从中序遍历、后序遍历中创建二叉树。

从中序遍历和后序遍历能还原唯一的二叉树,从中序遍历和前序遍历能还原唯一的二叉树。

513. 找树左下角的值

递归法

class Solution {
    public int maxDepth = Integer.MIN_VALUE;
    public int result;
    public int findBottomLeftValue(TreeNode root) {
        find(root, 0);
        return result;
    }
    public void find(TreeNode root, int depth){
        if (root == null) return;
        depth++;
        if(depth > maxDepth){
            maxDepth = depth;
            result = root.val; // 中
        }
        find(root.left, depth); // 左
        find(root.right, depth); // 右
    }
}

层序遍历法

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

112. 路径总和

class Solution {
    public Boolean res = false;
    public boolean hasPathSum(TreeNode root, int targetSum) {
        findPath(root, 0, targetSum);
        return res;
    }
    public void findPath(TreeNode root, int sum, int target){
        if(root == null) return;
        sum += root.val; //中
        if(root.left == null && root.right == null && sum == target){
            res = true;
        }
        findPath(root.left, sum, target); //左
        findPath(root.right, sum, target); //右
    }
}

113. 路径总和 II

class Solution {
    public List<List<Integer>> res = new LinkedList<>();
    public List<Integer> path = new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        findPath(root, 0, targetSum);
        return res;
    }
    public void findPath(TreeNode root, int sum, int target){
        if(root == null) return;
        path.add(root.val); //中
        sum += root.val; 
        if(root.left == null && root.right == null && sum == target){
            res.add(new ArrayList(path));
        }
        findPath(root.left, sum, target); // 左
        findPath(root.right, sum, target); // 右
        path.remove(path.size()-1); //回溯path, sum不需要回溯因为它是临时变量
    }
}

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

主要思路就是后序遍历的最后一个值就是根节点,我们只需要从后序遍历入手,再找到这个值在中序遍历的索引(需要一个哈希表),就能把中序遍历分成3份,分变为[左子树,根节点,右子树],再递归创建右子树和左子树,就能创建出整个树。

值得注意的是,一定要先创建右子树,因为只能从右子树中得到根节点,再得到所有右子树的根节点后,左子树的索引才能确定。

class Solution {
    public HashMap<Integer, Integer> map = new HashMap<>();
    public int postIndex;
    public int[] inorder;
    public int[] postorder;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        this.inorder = inorder;
        this.postorder = postorder;
        postIndex = postorder.length - 1;
        int i = 0;
        for(int n: inorder){
            map.put(n, i++);
        }
        return build(0, inorder.length - 1);
    }
    public TreeNode build(int inLeft, int inRight){
        if(inLeft > inRight) return null;
        int val = postorder[postIndex--];
        TreeNode root = new TreeNode(val);

        int index = map.get(val);

        root.right = build(index + 1, inRight);
        root.left = build(inLeft, index - 1);
        return root;
    }
}

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

class Solution {
    public HashMap<Integer, Integer> map = new HashMap<>();
    public int[] preorder;
    public int[] inorder;
    public int preIndex;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        this.inorder = inorder;
        preIndex = 0;
        int i = 0;
        for(int n : inorder){
            map.put(n, i++);
        }
        return build(0, preorder.length - 1);
    }
    public TreeNode build(int inLeft, int inRight){
        if(inLeft > inRight) return null;
        int val = preorder[preIndex++];
        TreeNode root = new TreeNode(val);
        int index = map.get(val);

        root.left = build(inLeft, index - 1);
        root.right = build(index + 1, inRight);

        return root;
    }
}