【Leetcode】树左下角的节点 / 路径总和Ⅱ / 从前序和中序遍历构造二叉树

513 树左下角的节点

和二叉树的右视图比较像。

先左后右访问,使用全局变量maxDepth,记录每个深度的第一个叶节点。

class Solution {
    int maxDepth = -1;
    int nodeLeft = 0;

    public int findBottomLeftValue(TreeNode root) {
        DFS(root, 0);
        return nodeLeft;
    }

    public void DFS(TreeNode root, int depth) {
        // 不处理root为null的情况,保证传入的root不等于null
        if (root.left == null && root.right == null) {
            if (depth > maxDepth) {
                maxDepth = depth;
                nodeLeft = root.val;
            }
        }
        TreeNode left = root.left;
        TreeNode right = root.right;

        if (left != null) {
            DFS(left, depth + 1);
        }

        if (right != null) {
            DFS(right, depth + 1);
        }
    }
}

112 路径总和

向下递归的过程中,targetSum递减。

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

        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }
}

113 路径总和Ⅱ

做第二遍了,还是思路不顺畅,希望这次记住吧~

  • 向下递归的过程中,targetSum递减。

  • 使用一个stack记录遍历时经过的路径,

  • 回溯:在DFS的过程中,先push进root,然后左子树、右子树遍历,再pop掉root。

  • 向容器中加入新路径的过程:即发现符合要求的叶子节点时加入stack,但需要new一个新的对象

import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

class Solution {
    List<List<Integer>> res = new LinkedList<List<Integer>>();
    // 使用一个stack
    Stack<Integer> stack = new Stack<>();

    public List<List<Integer>> pathSum (TreeNode root, int targetSum) {
        if (root == null) {
            return res;
        }
        DFS(root, targetSum);
        return res;
    }

    public void DFS (TreeNode root, int targetSum) {
        // 保证传入的值不为null
        // 向下递归的过程中,targetSum递减
        stack.push(root.val);

        if (root.left == null && root.right == null && targetSum == root.val) {
            // 新建一个path对象,加入当前的path
            res.add(new LinkedList<>(stack));
        }

        if (root.left != null) {
            DFS(root.left, targetSum - root.val);
        }

        if (root.right != null) {
            DFS(root.right, targetSum - root.val);
        }

        stack.pop();
        return;
    }
}

106 从前序遍历和中序遍历构造二叉树

由前序遍历得根节点,由中序遍历得左子树和右子树的范围,然后递归。

public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 前序遍历
        // 中序遍历
        return buildTree(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
    }

    public TreeNode buildTree(int[] preorder, int[] inorder, int l1, int r1, int l2, int r2) {
        // l1, r1代表preorder[l1, r1]
        // l2, r2代表inorder[l2, r2]

        if (l1 > r1) {
            return null;
        }

        // 这棵树根节点的值
        int rootVal = preorder[l1];
        TreeNode root = new TreeNode(rootVal);

        if (l1 == r1) {
            return root;
        }

        // 找到根节点在中序遍历中的位置:
        // 左:[l2, index - 1],index,右:[index + 1, r2]
        int index = l2;
        for (int i = l2; i <= r2; i++) {
            if (inorder[i] == rootVal) {
                index = i;
                break;
            }
        }

        int leftLength = index - l2;
        int rightLength = r2 - index;
        // 左子树在前序遍历中的位置: [l1 + 1, l1 + leftLength]
        // 右子树在前序遍历中的位置 [r1 - rightLength + 1, r1]
        root.left = buildTree(preorder, inorder, l1 + 1, l1 + leftLength, l2, index - 1);
        root.right = buildTree(preorder, inorder, r1 - rightLength + 1, r1, index + 1, r2);

        return root;
    }
}

你可能感兴趣的:(Leetcode题解总结,leetcode,java)