力扣506——和为K的子数组

https://leetcode.cn/problems/subarray-sum-equals-k/?envType=study-plan-v2&envId=top-100-liked

1. 用到了前缀和的概念:

给定一个数组nums,从该数组的初始位置元素开始相加,前缀和数组 prefixSum 的第 i 个元素表示从数组开头到第 i 个位置的元素之和。

对于数组 nums = [1, 2, 3, 4, 5],其前缀和数组 prefixSum[1, 3, 6, 10, 15]。其中,prefixSum[i] 表示数组 nums 中前 i+1 个元素的和。

2. 思路原理

(1) 为啥要计算前缀和?

当前缀和>target时,如果在前缀和中还存在“前缀和-target”,就说明数组中存在一截连续部分的和等于target

(2) 看看有几个符合要求的前缀和

total += 符合要求的前缀和的数量

(3)先判断还是先添加

假设我们的数组为 nums = [3, 4, 7, 2],目标值为 k = 7。我们用哈希表记录前缀和出现的次数。

  1. 首先,初始化前缀和哈希表,包含一个前缀和为 0 的情况:Prefix.put(0, 1)
  2. 遍历到第一个元素 3 时,前缀和为 3,将其添加到哈希表中,哈希表为 {0: 1, 3: 1}
  3. 遍历到第二个元素 4 时,前缀和为 3 + 4 = 7。此时我们检查哈希表中是否存在前缀和为 7 - 7 = 0,即是否存在以当前位置为结尾的子数组的和等于目标值 k。由于哈希表中存在前缀和为 0,我们将之前统计的子数组个数累加到结果中。然后,我们将当前前缀和 7 添加到哈希表中,哈希表为 {0: 1, 3: 1, 7: 1}
  4. 继续遍历数组,遍历到第三个元素 7 时,前缀和为 3 + 4 + 7 = 14。我们检查哈希表中是否存在前缀和为 14 - 7 = 7,即是否存在以当前位置为结尾的子数组的和等于目标值 k。由于哈希表中存在前缀和为 7,说明存在一个满足条件的子数组,我们将之前统计的子数组个数累加到结果中。

这样的例子说明了为什么在计算前缀和之前要先判断是否存在 sum - k 这样的前缀和,然后再将当前前缀和添加到哈希表中。这样能够保证正确地统计子数组的个数,避免出现错误的情况。

3. 完整代码

class Solution {
    public int subarraySum(int[] nums, int k) {
        int res = 0;
        int sum = 0;

        Map<Integer, Integer> Prefix = new HashMap<>();
        
        // 前缀和的初始化,key表示前缀和的值,value表示满足这个值的前缀和的个数
        Prefix.put(0,1);
        for(int i=0; i<nums.length; ++i){
            sum += nums[i];
            
            if(Prefix.containsKey(sum - k)){
                res += Prefix.get(sum-k);
            }

            // 得先判断前缀和map里是否已经存在了sum-k
            // 再添加新的sum
            Prefix.put(sum, Prefix.getOrDefault(sum,0)+1);

        }

        return res;

    } 
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值