【LeetCode 560】和为 K 的子数组

思路

前缀和

    public static int subarraySum(int[] nums, int k) {
    	int ret = 0;
    	Map<Integer, Integer> map = new HashMap<Integer, Integer>(); // 注1
    	int sum = 0;
    	map.put(0, 1);                                               // 注2
    	for (int i = 0; i < nums.length; i++)
    	{
    		sum += nums[i];
    		if (map.containsKey(sum - k))               // 因为j可以代表的和一定位于i之前, 
    			ret += map.get(sum - k);                // 所以这里很巧妙的保证了j一定位于i的前面 
    		map.put(sum, map.getOrDefault(sum, 0) + 1); // sum的范围是[j+1, i] 注3
    	}
    	return ret;
    }

【注1】这里map中的元素放置说明为<和, 可行的j的位置个数>;
【注2】这里需要提前加入元素<0, 1>,表示j-1时候,即不将j放入子数组,此时和为0,也是有可能的子数组序列;
【注3】这行代码不能调整到if之前。
在当前的代码顺序下,j的搜索范围为[-1, i-1],因此有效连续子数组的范围为[0, i],和[i, i]
如果将注1代码调整顺序到if之前的话,j的搜索范围为[-1, i],有效连续子数组的范围扩大到[i+1, i],显然是不合理的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值