代码随想录算法训练营第18天|513.找树左下角的值、112. 路径总和、113.路径总和ii、106.构造二叉树 105

57 阅读1分钟

今日内容 

●  513.找树左下角的值

●  112. 路径总和  113.路径总和ii

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

513. 找树左下角的值

class Solution {
    //用bfs最合适,理解上最直观
    //就是找到每一层的第一个,而且需要是叶子节点
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(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 && node.left == null && node.right == null) {
                    res = node.val;
                }
                if(node.left != null) {
                    queue.add(node.left);
                }
                if(node.right != null) {
                    queue.add(node.right);
                }
            }
        }
        return res;
    }
}

112. 路径总和

回溯问题

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

113. 路径总和 II

跟上一道题类似,只是把路径给打印出来了

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

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

分治法,后序遍历是左右中,通过后序遍历可以找到根节点,然后在中序遍历中可以找到根节点的下标,从而可以分割左右子树,递归分割即可构建二叉树

class Solution {
    HashMap<Integer, Integer> map;
    int[] postorder;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        this.postorder = postorder;
        for(int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        TreeNode root = build(0, inorder.length - 1, 0, postorder.length - 1);
        return root;
    }
    private TreeNode build(int is, int ie, int ps, int pe) {
        if(is > ie || ps > pe){
            return null;
        }
        int rootVal = postorder[pe];
        int inRootIndex = map.get(rootVal);
        TreeNode inRoot = new TreeNode(rootVal);
        inRoot.left = build(is, inRootIndex - 1, ps, ps + inRootIndex - 1 - is);
        inRoot.right = build(inRootIndex + 1, ie, ps + inRootIndex - is, pe - 1);
        return inRoot;
    }
}

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

跟上一道题思路一样

class Solution {
    HashMap<Integer, Integer> map;
    int[] preorder;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        int len = preorder.length;
        return buildTreeHelper(0, len - 1, 0, len - 1);
    }
    private TreeNode buildTreeHelper(int pStart, int pEnd, int iStart, int iEnd) {
        if(pStart > pEnd || iStart > iEnd) {
            return null;
        }
        int rootValue = preorder[pStart];
        TreeNode root = new TreeNode(rootValue);
        int inorderRootIndex = map.get(rootValue);
        int leftLen = inorderRootIndex - iStart;
        root.left = buildTreeHelper(pStart + 1, pStart + leftLen, iStart, inorderRootIndex - 1);
        root.right = buildTreeHelper(pStart + leftLen + 1, pEnd, inorderRootIndex + 1, iEnd);
        return root;
    }
}