- 和为K的子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
解题思路
误区:不要等计算完全部前缀和再去重新遍历查找是否有符合条件的,这样会有问题,比如k=0时,the_sum - k 一直等于the_sum,就算the_sum只有一个,结果的数量也会增加一,所以这样不对。应该每计算一个前缀和就在哈希表中进行查找,这样就不会查找到自己本身。
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
dict_sum = {0:1} # 考虑前缀和本来就为K的情况
the_sum = 0
ans = 0
ret = 0
for i in range(len(nums)):
# 每计算一个前缀和就在哈希表中查找一次,不要等全部计算完再去查找,因为只能和前面的数作差
the_sum += nums[i]
ans = the_sum - k # 查找哈希表中十分存在key为ans的
ret += dict_sum.get(ans, 0)
dict_sum[the_sum] = dict_sum.get(the_sum, 0) + 1 # 将该前缀和添加到哈希表中
return ret
- 和可被 K 整除的子数组
当两个数对k求模结果相同时,这两个数的差就能整除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]
class Solution(object):
def subarraysDivByK(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
前缀和的模相同时即可整除k
"""
# 求连续数组的和,连续数组的和可以表示为前缀和的差,比如 sum(A[i : j + 1]) = s[j + 1] - s[i]
s = [0] * (len(A) + 1) # s表示前缀和
kcnt = [0] * K # kcnt[i]代表s中有多少个元素 mod K 为i,索引代表余数值,数值表示余数为i的个数
for i in range(len(A)):
s[i + 1] = s[i] + A[i]
for item in s:
kcnt[item % K] += 1
return sum(x * (x - 1) // 2 for x in kcnt)