About 1 min

// 560. 和为K的子数组
class Solution {
    public int subarraySum(int[] nums, int k) {
        int[] sums = new int[nums.length + 1];
        for (int i = 0; i < nums.length; i++) {
            sums[i + 1] = sums[i] + nums[i];
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, 1); // 把前缀和 sums[0]=0 放进去
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            // 当前元素包括自身的[0...i]的数组和
            int sum = sums[i + 1];
            count += map.getOrDefault(sum - k, 0);
            map.put(sum, map.getOrDefault(sum, 0) + 1);
        }
        return count;
    }
}

前缀和 + 哈希表(记录前缀和出现的次数)

alt text

通过计算前缀和,我们可以将"和为 k 的连续子数组"问题转化为求解两个前缀和之差等于k的情况。

使用了一个哈希表 map 来记录前缀和出现的次数。这个哈希表的键是前缀和,值是前缀和出现的次数。

当我们遍历数组时,把一个从开始位置到当前元素(包括自己)的子数组分成两部分,前一部分的数组和是sum-k,后一部分的数组和是k。这个后一部分数组和是k的数组即为所求。

我们使用map来检查 sum-k 这一部分存在与否。如果存在,所求数组和是k的后半部分也存在。因此,我们可以通过 map.get(sum - k) 来获取到符合条件的子数组的个数。

并且,将当前元素包括自身的[0...i]的数组和,放入map中,次数+1。