• Day28——二叉树专题



    14.路径总和I

    思路dfs从根节点遍历到叶子节点,判断这条路径是否符合要求即可。

    class Solution {
        public boolean hasPathSum(TreeNode root, int targetSum) {
            return dfs(root,targetSum);
        }
        public boolean dfs(TreeNode root,int targetSum){
            if(root==null){
                return false;
            }
            if(root.left==null&&root.right==null){
                return targetSum==root.val;
            }
            return dfs(root.left,targetSum-root.val)||dfs(root.right,targetSum-root.val);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    15.路径总和II

    思路dfs

    class solution {
        public List> pathsum(TreeNode root, int targetsum) {
            List> res = new ArrayList<>();
            if (root == null) return res; // 非空判断
    
            List path = new LinkedList<>();
            preorderdfs(root, targetsum, res, path);
            return res;
        }
    
        public void preorderdfs(TreeNode root, int targetsum, List> res, List path) {
            path.add(root.val);
            // 遇到了叶子节点
            if (root.left == null && root.right == null) {
                // 找到了和为 targetsum 的路径
                if (targetsum - root.val == 0) {
                    res.add(new ArrayList<>(path));
                }
                return; // 如果和不为 targetsum,返回
            }
    
            if (root.left != null) {
                preorderdfs(root.left, targetsum - root.val, res, path);
                path.remove(path.size() - 1); // 回溯
            }
            if (root.right != null) {
                preorderdfs(root.right, targetsum - root.val, res, path);
                path.remove(path.size() - 1); // 回溯
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    解法二迭代法

    // 解法2
    class Solution {
        List<List<Integer>> result;
        LinkedList<Integer> path;
        public List<List<Integer>> pathSum (TreeNode root,int targetSum) {
            result = new LinkedList<>();
            path = new LinkedList<>();
            travesal(root, targetSum);
            return result;
        }
        private void travesal(TreeNode root,  int count) {
            if (root == null) return;
            path.offer(root.val);
            count -= root.val;
            if (root.left == null && root.right == null && count == 0) {
                result.add(new LinkedList<>(path));
            }
            travesal(root.left, count);
            travesal(root.right, count);
            path.removeLast(); // 回溯
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    16.路径总和III

    双重DFS:我们遍历每一个节点,从这个节点开始计算它的子树满足要求的路径。

    我们访问每一个节点 node,检测以node 为起始节点(头节点)且向下延深的路径有多少种(第二次dfs判断左右子树是否右满足的情况)。我们递归遍历每一个节点的所有可能的路径,然后将这些路径数目加起来即为返回结果。

    class Solution {
        int res = 0;
        public int pathSum(TreeNode root, int targetSum) {
            if(root == null){
                return 0;
            }
            long longTargetSum = targetSum;
            dfs(root, longTargetSum);// 每一个根节点都要dfs判断
            // 为下一次dfs做好准备
            pathSum(root.left, targetSum);
            pathSum(root.right, targetSum);
            return res;
        }
        public void dfs(TreeNode root, long sum){
            if(root == null){
                return ;
            }
            sum -= root.val;
            if(sum == 0){
                rse ++;
                // 这里不能return !! 下面可能还要答案集
            }
            dfs(root.left, sum);
            dfs(root.right, sum);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    17.从中序与后序遍历序列构造二叉树

    题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

    思路

    • 第一步:如果数组大小为零的话,说明是空节点了。
    • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
    • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
    • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
    • 第五步:切割后序数组,切成后序左数组和后序右数组
    • 第六步:递归处理左区间和右区间

    代码实现

    class Solution {
        Map<Integer, Integer> map;  // 方便根据数值查找位置
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            map = new HashMap<>();
            for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
                map.put(inorder[i], i);
            }
    
            return findNode(inorder,  0, inorder.length, postorder,0, postorder.length);  // 前闭后开
        }
        
        public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
            // 参数里的范围都是前闭后开
            if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树
                return null;
            }
            int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置
            TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
            int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数
            root.left = findNode(inorder, inBegin, rootIndex,
                                postorder, postBegin, postBegin + lenOfLeft);
            root.right = findNode(inorder, rootIndex + 1, inEnd,
                                postorder, postBegin + lenOfLeft, postEnd - 1);
    
            return root;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    18. 从前序与中序遍历序列构造二叉树

    题目链接105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

    思路看上一题即可

    代码实现

    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保存中序序列的数值对应位置
                map.put(inorder[i], i);
            }
    
            return findNode(preorder, 0, preorder.length, inorder,  0, inorder.length);  // 前闭后开
        }
    
        public TreeNode findNode(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 = findNode(preorder, preBegin + 1, preBegin + lenOfLeft + 1,  
                                inorder, inBegin, rootIndex);
            root.right = findNode(preorder, preBegin + lenOfLeft + 1, preEnd,
                                inorder, rootIndex + 1, inEnd);
            return root;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    Python行对齐工具difflib
    电脑文档数据恢复?别急,一招教你快速找回丢失数据!
    python-(4-6)数据类型的应用(文件操作)
    import一个“太极”库,让Python代码提速100倍
    玉米脱粒机设计全套
    腾讯轻联:带你创造属于自己的AI小助手
    >Web 3.0顶级干货教学:浅析区块链与货币关系
    工程竣工决算审计不同于竣工结算审核的十大要点
    863. 二叉树中所有距离为 K 的结点
    如何实现「零信任网络」安全体系结构?教你五步实现无边界安全
  • 原文地址:https://blog.csdn.net/weixin_54040016/article/details/127707635