zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    CSPS模拟 65
    CSPS模拟 64
    $color$有色图
    CSPS模拟 63
    CSPS模拟 62
    CSPS模拟 61
    CSPS模拟 60
    CSPS模拟 59
    go中单链表
    MYSQL-联合索引
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14187377.html
Copyright © 2011-2022 走看看