【前缀和】路径总和III & 和为k的子数组

437. 路径总和 III

给定一个二叉树,它的每个结点都存放着一个整数值。

找出路径和等于给定数值的路径总数。

路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

示例:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

返回 3。和等于 8 的路径有:

1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum-iii


常规思路:双递归,先序遍历的同时计算每个节点的路径和数量。

/**
 * 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 int pathSum(TreeNode root, int sum) {
        if(root == null){
            return 0;
        }
        int result = countPath(root,sum);
        int a = pathSum(root.left,sum);
        int b = pathSum(root.right,sum);
        return result+a+b;

    }
    public int countPath(TreeNode root,int sum){
        if(root == null){
            return 0;
        }
        sum = sum - root.val;
        int result = sum == 0 ? 1:0;
        return result + countPath(root.left,sum) + countPath(root.right,sum);
    }

}

  

方法二:前缀和?应该算记忆化递归

核心思路是,对于每一个节点值,其前往根节点的路径是唯一的。

借助p和数组array可以将当前节点通往根节点所在路径上的各个节点的值都储存下来。

 

class Solution {
    public int pathSum(TreeNode root, int sum) {
        return helper(root, sum, new int[1000], 0); //0表示根
    }

    //array数组存储某一次递归时所遍历结点的值,p表示当前节点的位置
    public int helper(TreeNode root, int sum, int[] array, int p){
        if(root == null){
            return 0;
        }    
        array[p] = root.val;
        int temp = 0;
        int n = 0;
  //计算当前节点到之前所有结点的路径和,看看有没有等于sum的
        for(int i=p; i>=0; i--){
            temp += array[i];
            if(temp == sum){
                n ++;
            }
        }
  //计算左右孩子到之前所有结点的路径和。有的话一起算上
        int left = helper(root.left, sum, array, p+1);
        int right = helper(root.right, sum, array, p+1);
        return n+left+right;
    }
}

作者:tian-ye
链接:https://leetcode-cn.com/problems/path-sum-iii/solution/di-gui-jie-fa-by-tian-ye/            

  

  

  

560. 和为K的子数组

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

示例 1 :

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :

数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-sum-equals-k

 

 

public class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0, pre = 0;
        HashMap < Integer, Integer > mp = new HashMap < > ();
        mp.put(0, 1);
        for (int i = 0; i < nums.length; i++) {
            pre += nums[i];
            if (mp.containsKey(pre - k)) {
                count += mp.get(pre - k);
            }
            mp.put(pre, mp.getOrDefault(pre, 0) + 1);
        }
        return count;
    }
}

  

 

posted @ 2021-02-04 11:26  A_Aron  阅读(158)  评论(0)    收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中