力扣——和为K的子数组

题目链接:

链接

题目描述:

在这里插入图片描述

思路:

思路一

子数组有两个边界,可以先固定左边界,然后遍历右边界,一边遍历一边求和
用两个for循环

思路二

用前缀和,前缀和就是数组累计求和
如【1 1 1】,前缀和【1 2 3】
i i i处的前缀和为 p r e ( i ) pre(i) pre(i),则:
p r e ( i ) = p r e ( i − 1 ) + n u m s [ i ] pre(i) = pre(i-1) + nums[i] pre(i)=pre(i1)+nums[i]
如果求某个子数组【i,j】的和,
s u m = p r e ( j ) − p r e ( i − 1 ) sum = pre(j) - pre(i-1) sum=pre(j)pre(i1)
我们现在知道了 p r e ( j ) pre(j) pre(j),所以只需要看有几个 p r e ( i − 1 ) = p r e ( j ) − s u m pre(i-1)=pre(j)-sum pre(i1)=pre(j)sum就行
如【1 1 1】,应该是【3-0】,所以要有一个初始的前缀和0

上面的公式类似于求两数之和,可以用map方便查找,
key是前缀和,value是前缀和的个数

实现代码:

class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0, n = nums.length; 
        //固定左
        for(int l = 0; l < n; l++){
            int sum = 0;
            //遍历右
            for(int r = l; r < n; r++){
                sum += nums[r];
                if(sum == k){
                    count++;
                }
            }
        }
        return count;
    }
}
class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0,1);
        int pre = 0,count = 0;
        for(int i = 0; i<nums.length; i++){
            pre += nums[i];
            if(map.containsKey(pre-k)) {
                count += map.get(pre-k);
            }
            map.put(pre,map.getOrDefault(pre,0)+1);
        }
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值