LeetCode560:和为K的子数组

要求

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。
在这里插入图片描述



思路

方法一:暴力解
先固定左边界,再去枚举右边

public int subarraySum(int[] nums, int k) {
    int count = 0;
    int len = nums.length;
    for (int left = 0; left < len; left++) {
        int sum = 0;
        // 区间里可能会有一些互相抵销的元素
        for (int right = left; right < len; right++) {
            sum += nums[right];
            if (sum == k) {
                count++;
            }
        }
    }
    return count;
}

方法二:前缀和 + 哈希表
我们先了解一下前缀和
我们求数列的和时,Sn = a1+a2+a3+…an; 此时Sn就是数列的前 n 项和。例 S5 = a1 + a2 + a3 + a4 + a5; S2 = a1 + a2。所以我们完全可以通过 S5-S2 得到 a3+a4+a5 的值;我们的前缀和数组里保存的就是前 n 项的和。
在这里插入图片描述
我们通过前缀和数组保存前 n 位的和,presum[1]保存的就是 nums 数组中前 1 位的和,也就是 presum[1] = nums[0], presum[2] = nums[0] + nums[1] = presum[1] + nums[1];
例如我们需要获取 nums[2] 到 nums[4] 这个区间的和,我们则完全根据 presum 数组得到
在这里插入图片描述



public class LeetCode560 {
    public int subarraySum(int[] nums, int k) {
        if (nums == null){
            return 0;
        }
        // key:前缀和,value:key 对应的前缀和的个数
        HashMap<Integer, Integer> map = new HashMap<>();

        //细节,这里需要预存前缀和为 0 的情况,否则会漏掉从第一位开始就满足的情况
        //例如输入[1,1,0],k = 2 如果没有这行代码,则会返回0,漏掉了1+1=2,和1+1+0=2的情况
        //输入:[3,1,1,0] k = 2时则不会漏掉
        //preSum[3] - preSum[0]表示前面 3 位的和,所以需要map.put(0,1),垫下底
        map.put(0,1);
        //记录需要返回的总数;前缀和
        int count = 0,preSum = 0;
        for (int num : nums) {
            preSum += num;
            //当前前缀和已知,判断是否含有preSum - k的前缀和,那么我们就知道某一区间的和为 k 了。
            if (map.containsKey(preSum - k)){
                //获取次数:map集合中的value
                count += map.get(preSum - k);
            }
            map.put(preSum,map.getOrDefault(preSum,0) + 1);
        }
        return count;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值