mengjian-github / leetcode

leetcode前端题目笔记

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

560. 和为 K 的子数组

mengjian-github opened this issue · comments

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。

 

示例 1:

输入:nums = [1,1,1], k = 2
输出:2
示例 2:

输入:nums = [1,2,3], k = 3
输出:2

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/subarray-sum-equals-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题比较容易的思路是暴力解:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var subarraySum = function(nums, k) {
    let result = 0;

    for (let i = 0; i < nums.length; i++) {
        let sum = 0;
        for (let j = i; j < nums.length; j++) {
            sum += nums[j];
            if (sum === k) {
                result++;
            }
        }
    }

    return result;
};

这道题可以使用前缀和来优化时间复杂度:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
var subarraySum = function(nums, k) {
    const map = new Map();
    let pre = 0;
    let result = 0;

    // 初始化前缀和第一个为0,因为前缀和的差值是左边的下标多减了1
    map.set(0, 1);

    for (let i = 0; i < nums.length; i++) {
        pre += nums[i];

        // 实际上在前缀和数组里,pre[i] - pre[j-1] = k
        // 所以这里直接找pre[i] - k在不在之前存的map里,它出现过几次,就是找到了几个k的可能性
        const target = pre - k;
        if (map.has(target)) {
            result += map.get(target);
        }

        if (map.has(pre)) {
            map.set(pre, map.get(pre) + 1)
        } else {
            map.set(pre, 1);
        }
    }

    return result;
};