974.和可被K整除的子数组
Contents
974. 和可被 K 整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
示例:
输入:A = [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]
提示:
1 <= A.length <= 30000 -10000 <= A[i] <= 10000 2 <= K <= 10000
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/subarray-sums-divisible-by-k 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
思路一:
此题目跟 560 题 非常类似。 我们同样先采用暴力法两层循环去解决问题。
- // 暴力法
- // 两层循环
- // 思路简单,从头开始遍历, i表示 子数组的开始位置,j表示 子数组的结束位置
- // 当和对 k 取余 == 0, result++
- // 最终返回 result
- // 时间复杂度 : O(N ^ 2), 其中N为数组的长度
- // 空间复杂度 : O(1)
- // 代码逻辑没问题, 但是提交后, 超时了
- // 时间复杂度太高
代码如下:
|
|
利用前序和 , 哈希表优化
-
前序和,是指从数组第0项,到数组当前项的总和
-
如果用数组 prefixsum 表示
-
prefixsum[i] 为数组 第0项,到数组第 i 项的总和
-
所以 nums 第 i 项到 第 j 项的总和为 prefixsum[j] - prefixsum[i - 1]
-
题目等价交换
-
有几种i, j组合,使得 nums[i] 累加到 nums[j] 的总和为 k
-
有几种i, j组合,使得 prefixsum[j] - prefixsum[i -1] == k
-
引入哈希表
-
哈希表中存放 <前序和 :出现次数>
-
当遍历到数组某一位置时,如果其前序和 与 K的差值,在哈希表中存在
-
则次数 += map.get(前序和 - 差值)
-
map中赋值当前前序和,如果之前有,则+1, 没有则赋值1
-
时间复杂度 O(N)
-
空间复杂度 O(N)
-
上述是 题目 560 的解题步骤
-
974 与 560的不同之处在于 取模
-
(P[j] - P[i]) % k == 0
-
根据同余定理 P[j] % K == P[i] % K;
-
所以本题中,字典存放 <前序和 % K, 出现次数>
代码如下:
|
|
时间复杂度 : O(N). 遍历了一遍数组,其中N为数组中元素的个数
空间复杂度: O(N). 额外使用了hashmap内存空间
Author 飞熊
LastMod May 27