[Leetcode 974]连续子数组的前缀和,哈希表

解题思路

凡是“连续子数组求和”问题,都可以套入下面的逻辑公式

  1. 假设用s[i][j]表示连续子数组a[i:j]的和, 则不难看出s[i][j] = s[0][j] - s[0][i];
  2. s[0][i]s[0][j] 同时满足某种条件时 => s[i][j] 可满足某种条件

容易看出在本题中,当(s[0][j] - s[0][i]) % K == 0时,s[i][j]就是符合条件的子数组,即
s[0][j] % K == s[0][i] % K

  • s[0][i]sum,我们将 key = sum%K 作为哈希表的键,值为其出现的次数hash[key] = n
  • 如果hash[key] > 0,说明存在n个k使得s[0][k]%K == key,即存在nA[k:i]可被K整除
  • 特殊情况1,sum%K == 0本身满足条件,初始条件hash[0] = 1
  • 特殊情况2,sum%K < 0,需要转为正数key = (K+sum%K)%K

代码

/**
 * @param {number[]} A
 * @param {number} K
 * @return {number}
 */
var subarraysDivByK = function(A, K) {
    let dp = new Array(K).fill(0),sum = 0, ret = 0;
    dp[0] = 1;
    for (let i=0;i<A.length;i++) {
        sum += A[i];
        let key = (K+sum%K)%K;// 消除负数
        if (dp[key]) {
            ret += dp[key];
        }
        dp[key]++;
    }
    return ret;
};

相似题目

  1. 560. 和为K的子数组 -- 将元素求和sum作为哈希表的键
  2. 1371. 每个元音包含偶数次的最长子字符串 -- 将元音字符出现的奇偶次数状态组合作为哈希表的键
posted @ 2020-05-27 13:59  真理君的宿敌  阅读(175)  评论(0编辑  收藏  举报