class Solution:
def checkSubarraySum(self, nums: List[int], k: int) -> bool:
#暴力出错
prefix_sum = [nums[0]]
for i in range(1,len(nums)):
prefix_sum.append(prefix_sum[-1]+nums[i])
for i in range(1,len(prefix_sum)):
if prefix_sum[i]%k==0:
return True
j=0
while i-j>=2:
if (prefix_sum[i]-prefix_sum[j])%k==0:
return True
j+=1
return False
#先计算前缀和
prefix_sum = [0]
for num in nums:
prefix_sum.append(prefix_sum[-1]+num)
#记录前缀和余数第一次出现的位置
dic = {0:0}
for i in range(1,len(prefix_sum)):
key = prefix_sum[i]%k
if key in dic:
value = dic[key]
#如果和首次出现的位置是大于2,那么就返回True
if i-value>=2:
return True
else:
#如果没出现在字典中,添加进去即可
dic[key] = i
return False
题目分析
- 暴力法
- 暴力出奇迹,结果就是超时
- 先计算前缀和,然后在遍历两个前缀和之间的差值是不是整除k,而且索引的差值大于2
- 前缀和+hash
- 计算前缀和
- 利用hash表保存首次出现余数的位置
- 只要两个前缀和位置的余数相同,且索引的位置值之差是大于2即可
一般处理连续问题都是需要利用前缀和去做的