本文主要是介绍leetcode-523. 连续的子数组和,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
给定一个包含非负数的数组和一个目标整数 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。
说明:
数组的长度不会超过10,000。
你可以认为所有数字总和在 32 位有符号整数范围内。
解题思路
前缀和的题目,与和可被 K 整除的子数组(前缀和+取模)非常类似,区别有2个:
- 这次不是取模,而是倍数,所以需要考虑0的问题。比如:
k可能为0,所以[23, 0, 0], 0
是符合要求的
k的0倍也是k的倍数,所以[23, 0, 0], 6
也是符合要求的。(sum([0, 0]) = 0
,0是6的0倍) - 题目要求长度
>= 2
的数组才算,所以前缀和字典中应该保存和的下标
在代码的处理上,大致思路和被K整除是相似的,注意2点:
- 求和是k的倍数,写成代码是:
(cur_sum - k) % k == 0
,数学上可以写成:cur_sum % k == 0
,如果k不为0,则每次都对cur_sum
求模,如果有相同的cur_sum
出现,则可以说明,2个cur_sum
之间的差一定是k的倍数 - 因为本题需要返回是否存在,所以如果2个
cur_sum
相同,保留最靠前的index,以便后面使用时,画出的子数组是最长的
代码
class Solution:def checkSubarraySum(self, nums: List[int], k: int) -> bool:pre_sum = {0: -1}cur_sum = 0for index, each_num in enumerate(nums):cur_sum += each_numif k != 0:cur_sum %= klength = index - pre_sum.get(cur_sum, index)if length >= 2:return Truepre_sum[cur_sum] = pre_sum.get(cur_sum, index)return False
这篇关于leetcode-523. 连续的子数组和的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!