day18 【二叉树】513.找树左下角的值 |112.路径总和 | 113.路径总和Ⅱ | 106.从中序与后序遍历序列构造二叉树 |105.从前序与中序遍历序列构造二叉树

513.找树左下角的值

  • 513.找树左下角的值 | 题目链接
  • 代码随想录 | 讲解链接
  • 题意:给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
  • 思路:递归。找到深度最深的那一条路径,返回这条路径上的叶子几点即可。那么在递归时就要计算深度depth,并且通过回溯,计算每一条路的depth。
    1. 递归函数的参数和返回值:参数为根节点root,用int类型的depth记录深度。不需要返回值,返回类型为void。
    2. 确定终止条件:当遇到叶子节点时(一个节点的左右节点都为null),就更新此时的最大深度。
    3. 确定单层递归的逻辑:前序遍历。遇见中间节点就统计深度,遇见左右孩子节点就递归遍历往下走,传入深度为depth+1
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //记录最大深度
    int maxDepth = 0;
    //记录最大深度路径的叶子节点的值
    int value = 0;
    public int findBottomLeftValue(TreeNode root) {
        value = root.val;
        findDepthValue(root, 0);
        return value;
    }

    public void findDepthValue(TreeNode root, int depth) {
        //如果根节点为null,就结束递归
        if(root == null) {
            return;
        }
        //如果节点的左右孩子都是空,那此节点就是这条路径的叶子节点,比较这条路径的深度和最大深度,及时更新最大深度的值
        if(root.left == null && root.right == null) {
            if(depth > maxDepth) {
                maxDepth = depth;
                value = root.val;
            }
        }
        //如果节点的左右孩子不为空,就继续递归遍历
        if(root.left != null) {
            findDepthValue(root.left, depth + 1);
        }
        if(root.right != null) {
            findDepthValue(root.right, depth + 1);
        }
    }
}

112.路径总和

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        //剪枝,如果是空树,就直接返回false
        if(root == null) {
            return false;
        }

        targetSum -= root.val;
        if(root.left == null && root.right == null) {
            return targetSum == 0;
        }

        if(root.left != null) {
            //看左孩子的孩子是否有满足题意的路径,有就一路往上返回true
            if(hasPathSum(root.left,targetSum)) {
                return true;
            }
        }

        if(root.right != null) {
            if(hasPathSum(root.right, targetSum)) {
                return true;
            }
        }
        return false;
    }
}

113.路径总和Ⅱ

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        //存放结果
        List<List<Integer>> res = new ArrayList<>();
        //非空判断
        if(root == null) {
            return res;
        }
        //存放每条符合条件的路径
        List<Integer> path = new LinkedList<>();
        preorderfs(root, targetSum, res, path);
        return res;
    }

    public void preorderfs(TreeNode root, int targetSum, List<List<Integer>> res,
                           List<Integer> path) {
        //把此时的根节点放到路径里
        path.add(root.val);
        //遇到叶子节点,判断此时的targetsum-节点是否为0
        if(root.left == null && root.right == null) {
            if(targetSum - root.val == 0) {
                //如果为0,这条path符合条件,把path加入到res中
                res.add(new ArrayList<>(path));
            }
            return;
        }

        if(root.left != null) {
            //传入左孩子,tagetsum减去根节点的值
            preorderfs(root.left, targetSum - root.val, res, path);
            //回溯,删除path中最后一个元素
            path.remove(path.size() - 1);
        }

        if(root.right != null) {
            preorderfs(root.right, targetSum - root.val, res, path);
            path.remove(path.size() - 1);
        }
    }
}

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

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //方便根据数值查找位置
    Map<Integer, Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        //把中序存到map中便于查询位置
        for(int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return finNode(inorder, 0, inorder.length, postorder, 0, postorder.length);

    }

    public TreeNode finNode(int[] inorder, int inBegin, int inEnd,
                            int[] postorder, int postBegin, int postEnd) {
        //不满足左闭右开就结束
        if(inBegin >= inEnd || postBegin >= postEnd) {
            return null;
        }
        //每一棵树根节点就是后序数组的最后一个元素也就是postdorder[postEnd-1].
        //根据后序遍历获取根节点后,在前序遍历中找到根节点,以此为界限分割左右孩子
        //map中存放的就是前序遍历的值和索引,map.get(根节点)就是查到根节点在前序遍历中的位置
        int rootIndex = map.get(postorder[postEnd - 1]);
        //构造二叉树的根节点
        TreeNode root = new TreeNode(inorder[rootIndex]);
        //根据根节点的位置,把中序数组划分为左右子树两部分。
        //左子树是左闭右开,长度就是根节点的索引 - 开始节点的索引
        int lenOfLeft = rootIndex - inBegin;
        //递归划分子树

        //划分左子树,传入的inorder还是原先的,但根据inBein和inEnd的值的改变
        //从前序数组中划分左子树,inBegin还是原来的,但是结束的范围已经变为根节点的索引值,由于是左闭右开,所以可以写到根节点的索引值。在根节点之前都是左子树
        //再划分后序遍历,传入的还是后序数组
        root.left = finNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft);
        //根节点的右子树,就是划分的前序数组的后半部分,索引从rootIndex + 1开始到inEnd。
        //划分后序数组中的右子树,就是postBegin + 左子树的长度,到后续数组长度 - 1.
        root.right = finNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1 );
        return root;
    }
}

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

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer, Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return finNode(preorder, 0, preorder.length, inorder, 0, inorder.length);
    }

    public TreeNode finNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {
        if(preBegin >= preEnd || inBegin >= inEnd) {
            return null;
        }
        int rootIndex = map.get(preorder[preBegin]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenOfleft = rootIndex - inBegin;

        root.left = finNode(preorder, preBegin + 1, preBegin + 1 + lenOfleft, inorder, inBegin, rootIndex);
        root.right = finNode(preorder, preBegin + lenOfleft + 1, preEnd, inorder, rootIndex + 1, inEnd);
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuwuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值