LeetCode 560 : Subarray Sum Equals K(java)

子序列和为k的计数

原题

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:
Input:nums = [1,1,1], k = 2
Output: 2

Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

思路

本题求在一个数组中,连续子序列和为k的子序列(子序列长度为1-n均可,其中n为数组的大小)的个数。
解题的思路是用一个sum记录前i个数的和,若sum[i]-sum2[j]=k,则说明下标从j到i-1的数的和为k,用两层for循环的思路易求得本题的答案。时间复杂度为o(n^2)。
但有没有更好的思路呢?当然是有!有o(n)的思路!用hashmap!怎么用?举个例子:若已知nums=[1,2,-1,-1,1,5],k=1。若用sums表示前i个数的和,那么有sums=[1,3,2,1,2,7]。我们用列举法来走一组循环,i从0到5。已知hashmap[0]=1(大家可以思考下为什么要有这个初始化)。
(1)i=0,hashmap[1]=1,k=1,这种情况符合要求;
(2)i=1,hashmap[3]=1,hashmap[1]=1,sums[1]=3,sums[1]-k=2,无符合要求的情况;
(3)i=2,hashmap[3]=1,hashmap[1]=1,hashmap[2]=1,此时sums[2]-sums[0]=2-1=1=k,这种情况符合要求,在这种情况下,其实就是求hashmap[sums[2]-k]的值,刚好hashmap[1]=1;
(4)i=3,hashmap[3]=1,hashmap[1]=2(和为1的子序列数为2个,分别为sums[0]=sumof([1])=1和sums[3]=sumof([1,2,-1,-1])=1),hashmap[2]=1,sums[3]=1,sums[3]-k=0,hashmap[0]=1,符合要求,其实这种情况也就是前4个数之和为k;
(5)i=4,hashmap[3]=1,hashmap[1]=2,hashmap[2]=2,此时sums[4]=2,已知k=1,若sums[j]=1(j<4),那么有sums[4]-sums[j]=1=k,此时要求sums[j]=sums[4]-k的符合要求的j的个数,由于hashmap已经有对i个数的和进行了存储,查询得hashmap[1]=2,说明此时j有j=0和j=3两个选择;
(6)i=5,hashmap[3]=1,hashmap[1]=2,hashmap[2]=2,hashmap[7]=1,此时sums[5]=7,k=1,求sums[j]=7-1=6的个数,此时为0。
综上,答案为1+1+1+2=5。
不知道这么解释有没有说清楚,感觉有点词不达意,汗!直接上java代码吧!细节不再赘述,一切尽在代码中!

代码

public class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer,Integer> map=new HashMap<>();
        int sum=0,count=0;
        map.put(0,1);
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
            if(map.containsKey(sum-k))
                count+=map.get(sum-k);
            //map.put(sum, map.getOrDefault(sum, 0) + 1);
            if(map.containsKey(sum))
                map.put(sum,map.get(sum).intValue()+1);
            else
                map.put(sum,1);
        } 
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值