给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。
示例 1:
输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:
输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
解题思路
本题要找一个子数组的和是k的整数倍,利用性质 两个数除k的余数相同则这两个数的差是k的整数倍 。利用哈希表保存余数,每个字典的key为余数,value为该余数第一次出现对应的索引index。当第二次出现相同的余数时,要判断是否和第一次出现的余数的索引之差大于等于2,因为子数组至少为2。在默认初始化的哈希表中添加key为0的项,考虑前n项和刚好是k的整数倍的情况。
class Solution(object):
def checkSubarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
除以k的余数相同则两数之差是6的倍数
"""
dict_m = {0: -1}
total = 0
for i in range(len(nums)):
total += nums[i]
if k!=0:
# 如果k!=0的话,就保留除k的余数,要问两个数除k的余数相同则这两个数的差是k的整数倍
total = total % k
# 如果k==0,则直接保留前缀和
if total in dict_m and (i - dict_m[total] > 1):
return True
elif total not in dict_m:
dict_m[total] = i
return False