threedayAAAAA / alg-exercise

算法训练
0 stars 0 forks source link

【基础篇 - Day 24】 2023-03-08 - 974. 和可被 K 整除的子数组 (04. 哈希表) #26

Open threedayAAAAA opened 1 year ago

threedayAAAAA commented 1 year ago

给定一个整数数组 nums 和一个整数 k ,返回其中元素之和可被 k 整除的(连续、非空) 子数组 的数目。

子数组 是数组的 连续 部分。

 

示例 1:

输入:nums = [4,5,0,-2,-3,1], k = 5 输出:7 解释: 有 7 个子数组满足其元素之和可被 k = 5 整除: [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] 示例 2:

输入: nums = [5], k = 9 输出: 0  

提示:

1 <= nums.length <= 3 * 104 -104 <= nums[i] <= 104 2 <= k <= 104

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

threedayAAAAA commented 1 year ago

方法一

思路

暴力搜索,直接搜索 i 到 j中和能否被k整除

代码

function subarraysDivByK(nums: number[], k: number): number {
    let result = 0
    const sumArr = nums.reduce((pre, item, index) => {
        pre.push(index === 0 ? item : pre[index - 1] + item)
        return pre
    }, [])
    for(let i = 0; i < nums.length; i++){
        for(let j = i; j < nums.length; j++){
            if((sumArr[j] - sumArr[i] + nums[i]) % k === 0) result++
        }
    }
    return result
};

时空复杂度

方法二

思路

根据同余定理,a % k === b % k 那么a -b 一定能被k整除

代码

function subarraysDivByK(nums: number[], k: number): number {
    let result = 0
    const dataMap = { 0: 1 }
    let sum = 0
    for(const item of nums){
        sum += item
        const key = ((sum % k) + k) % k
        dataMap[key] = dataMap[key] ? dataMap[key] + 1 : 1
        result += dataMap[key] - 1
    }
    return result
};

时空复杂度

yunliuyan commented 1 year ago

思路

function subarraysDivByK(nums: number[], k: number): number {
    let res = 0, sum = 0;
    const hashMap: Map<number, number> = new Map();
    // 0默认存在
    hashMap.set(0, 1);
    for(const num of nums) {
        sum += num;
        const remainder = (sum % k + k) % k;
        if (hashMap.has(remainder)) {
            res += hashMap.get(remainder)
        } 
        hashMap.set(remainder, (hashMap.get(remainder) ?? 0) + 1);
    }
    return res;
};

复杂度分析