代码随想录Day18 | 513. 找树左下角的值、112. 路径总和、105. 从前序与中序遍历序列构造二叉树 | 二叉树、递归、回溯

58 阅读2分钟

513. 找树左下角的值

题目链接:513. 找树左下角的值

思路: 这题用层序遍历的话非常简单,先加入节点的右孩子到队列,再加入左孩子,每遍历到一个节点更新res的值,最后出来的节点是树的左下角。

用递归的话,二叉树递归框架代码是先递归左子树,后递归右子树,所以到最大深度时第一次遇到的节点就是左下角的节点。定义depth为当前节点深度,maxdepth为最大深度,使用回溯,每到一个节点,depth++,如果大于最大深度maxdepth,那么把depth的值赋给maxdepth,并把该节点的值赋给res,再遍历左子树和右子树。

class Solution {

    int maxdep = 0;
    int dep = 0;
    int res = 0;

    public int findBottomLeftValue(TreeNode root) {
        // res = root.val;
        traverse(root);
        return res;
    }

    void traverse(TreeNode root) {
        if (root == null) {
            return;
        }
        dep++;
        if (dep > maxdep) {
            maxdep = dep;
            res = root.val;
        }
        traverse(root.left);
        traverse(root.right);
        dep--;
    }
}

总结:

112. 路径总和

题目链接:112. 路径总和

思路: 这题用到回溯就可以,定义全局变量sum,每遍历到一个节点,前序位置 sum += node.val,如果该节点为叶子节点,并且sum == target,那么存在路径。递归遍历左右子树,后序位值 sum -= node.val。

class Solution {

    int sum = 0;
    boolean check = false;

    public boolean hasPathSum(TreeNode root, int targetSum) {
        traverse(root, targetSum);
        return check;
    }

    void traverse(TreeNode root, int target) {
        if (root == null) {
            return;
        }

        sum += root.val;

        if (root.left == null && root.right == null && sum == target) {
            sum -= root.val;
            check = true;
            return;
        }

        traverse(root.left, target);
        traverse(root.right, target);
        sum -= root.val;
    }
}

总结:

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

题目链接:105. 从前序与中序遍历序列构造二叉树

思路:

构造二叉树,第一件事一定是找根节点,然后想办法构造左右子树。前序遍历结果第一个就是根节点的值,然后再根据中序遍历结果确定左右子树的节点。

我的代码:

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return build(preorder, 0, preorder.length - 1,
                    inorder, 0, inorder.length - 1);
    }

    TreeNode build(int[] preorder, int preStart, int preEnd,
                    int[] inorder, int inStart, int inEnd) {
        if (preStart > preEnd) {
            return null;
        }
        int rootVal = preorder[preStart];
        int index = 0;
        for (int i = 0; i < inorder.length; i++) {
            if (inorder[i] == rootVal){
                index = i;
                break;
            }
        }

        TreeNode root = new TreeNode(rootVal);
        int leftsize = index - inStart;
        root.left = build(preorder, preStart + 1, preStart + leftsize,
                            inorder, inStart, index - 1);
        root.right = build(preorder, preStart + leftsize + 1, preEnd,
                            inorder, index + 1, inEnd);
        return root;
    }
}

总结: