• LeetCode437. 路径总和 III


    【举一反三】:在二叉树中找到累加和为指定值的最长路径长度  ------ 左神P115

    ☆☆☆☆思路1:双重递归,第一个递归用来遍历这些节点,这二个递归用来处理这些节点,进行dfs。

        思路1的缺点是存在大量重复计算,时间效率差

    ☆☆☆☆☆思路2:前缀和 递归回溯。  时间复杂度为O(n),空间复杂度为O(n)

    代码1.1:

    class Solution {
        // 在以root为根节点的二叉树中,寻找和为sum的路径,返回这样的路径个数
        public int pathSum(TreeNode root, int sum) {
            if (root == null) return 0;
    
            // 每一个节点寻找的路径数 由 三部分构成
            int res = findPath(root, sum);
            res += pathSum(root.left, sum);
            res += pathSum(root.right, sum);
            return res;
        }
        // 在以node为根节点的二叉树中,寻找包含node的路径,和为num
        // 返回这样的路径个数
        private int findPath(TreeNode node, int num) {
            if (node == null) return 0; // 可以一直搜索到null
            int res = 0;
    
            if (node.val == num) {
                res += 1;  // 不能直接return,因为值有负数的情况
            }
            res += findPath(node.left, num - node.val);
            res += findPath(node.right, num - node.val);
    
            return res;
        }
    }

    代码1.2:

    class Solution {
        int count = 0;
        public int pathSum(TreeNode root, int sum) {
            if (root == null) return 0;
            dfs(root, sum);
            pathSum(root.left, sum);
            pathSum(root.right, sum);
            return count;
        }
        private void dfs(TreeNode node, int num) {
            if (node == null) return;
            if (node.val == num) {
                count ++;
            }
            dfs(node.left, num - node.val);
            dfs(node.right, num - node.val);
        }
    }

    代码2:前缀和, 参考:前缀和,递归,回溯

    class Solution {
        public int pathSum(TreeNode root, int sum) {
            // key是前缀和, value是大小为key的前缀和出现的次数
            Map<Integer,Integer> map = new HashMap<>();
            // 当(pathSum-sum = 0)时,说明当前路径符合要求,res + 1
            map.put(0, 1);
            return dfs(root, map, 0, sum);
        }
        private int dfs(TreeNode root, Map<Integer,Integer> map, int curSum, int target) {
            // 1.递归终止条件
            if (root == null) return 0;
            // 2.本层要做的事情
            curSum += root.val;
            int res = 0;
            // currSum-target相当于找路径的起点,起点的sum+target=currSum,当前点到起点的距离就是target
            res += map.getOrDefault(curSum - target, 0);
            map.put(curSum, map.getOrDefault(curSum, 0) + 1);
            // 3.进入下一层
            res += dfs(root.left, map, curSum, target);
            res += dfs(root.right, map, curSum, target);
            // 4.回到本层,左右子树遍历完后,恢复状态(因为这个路径不可能是别的路径的前缀了)
            map.put(curSum, map.get(curSum) - 1);
            return res;
        }
    }
  • 相关阅读:
    土法炼钢:怎么实现一个简单的B+Tree In-Disk
    panguan(判官):一个自研的任务执行引擎的工程实践
    团队源代码管理
    测试——俄罗斯方块
    测试——连连看
    测试——食物链教学小工具
    测试——约跑APP
    beta-review阶段贡献分分配
    第十周PSP&进度条
    吉林市一日游
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14187377.html
Copyright © 2020-2023  润新知