问题:
给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:
子数组大小 至少为 2 ,且子数组元素总和为 k 的倍数。
如果存在,返回 true ;否则,返回 false 。
如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。0 始终视为 k 的一个倍数。
示例 1:
输入:nums = [23,2,4,6,7], k = 6
输出:true
解释:[2,4] 是一个大小为 2 的子数组,并且和为 6 。
分析:
首先确保已经掌握力扣560.和为K的子数组,我的题解
仍然利用前缀和+哈希表来解。这题和560的区别是:i和j之间的关系式变成了prefix_num[j]-prefix_num[i]=nk (j-i>=2)(n=0,1,2…)。按560题的思路,我们遍历j,遍历j的同时,计算前缀和,把前缀和存入哈希表之前,判断哈希表里是否有key=prefix_num[j]-nk, 然后取出value,那么问题来了,这里要找的key不是一个固定值,因为n是个变量哇!而且这个n的取值题目中没有限制,就算限制了是不是又得加一个循环结构,增加了时间。那我们想想能不能根据prefix_num[j]-prefix_num[i]=n*k这个关系式推出一个i,j之间的固定关系???
哎呀,我反正是没想到哒!咱就是说看过答案之后理解记住就行!根据这个关系式,我们可以知道:prefix_num[j]=nk+prefix_num[i]
prefix_num[i]=-nk+prefix_num[j]
但是他们两之差2nk+prefix_num[i]-prefix_num[j]是k的倍数,
是不是说明prefix_num[i],prefix_num[j]%k的余数相等。
欧克!找到了i,j前缀和之间的固定关系,关系式里没有变量
但是还有一个问题,怎么保证根据%k余数相等,去哈希表找到的(i的)前缀和,这个i满足j-i>2!!!看题目!!!题目要求只需找到一个满足条件的数组,所以我们可以用哈希表的value存前缀和为key的元素下标,且这个value一旦被赋值就不要去替换,因为越靠前的i,能更快的满足j-i>2
代码实现:
class Solution(object):def checkSubarraySum(self, nums, k):""":type nums: List[int]:type k: int:rtype: bool"""# 连续子数组(个数>=2)元素和为0 or k倍数# 找到一个满足j-i>=2 l[j]-l[i]=n*k n=0,1,,, 哈希表存prefix_sum->indexn=len(nums)count=0d=dict()prefix_num=0d[0]=-1for i in range(n):prefix_num+=nums[i]# tmp=prefix_num-nk 这里需要处理一下# l[j]-l[i]=n*k l[j]=n*k+l[i] l[i]=l[j]-n*k 可以推出l[j]和l[i]%k的余数一定相等tmp=prefix_num%kif tmp in d and i-d[tmp]>=2:return Trueif tmp not in d:d[tmp]=ireturn False