[20210602]LeetCode每日一题 - 523. 连续的子数组和
作者:互联网
题目描述【中等】
给你一个整数数组
nums
和一个整数k
,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小 至少为
2
,且 子数组元素总和为k
的倍数。 如果存在,返回true
;否则,返回false
。如果存在一个整数
n
,令整数x
符合x = n * k
,则称x
是k
的一个倍数。
示例 1:
输入:
nums = [23,2,4,6,7]
,k = 6
输出:true
解释:[2,4]
是一个大小为2
的子数组,并且和为6
。
示例 2:
输入:
nums = [23,2,6,4,7]
,k = 6
输出:true
解释:[23, 2, 6, 4, 7]
是大小为5
的子数组,并且和为42
。
42
是6
的倍数,因为42 = 7 * 6
且7
是一个整数。
示例 3:
输入:
nums = [23,2,6,4,7]
,k = 13
输出:false
提示:
1 <= nums.length <= 10^5
0 <= nums[i] <= 10^9
0 <= sum(nums[i]) <= 2^31 - 1
1 <= k <= 231 - 1
题目地址:地址
初步分析
本题涉及到一个算法:前缀和
-
何为
前缀和
?
前缀和是为了快速求解类似于此类需要做 连续加法 的题而使用的数学工具。简单来说,就是一个新的、长度和原数组相同的数组sum
,sum
的第i
项是原数组 从0
~i
的和。 -
举个例子
例:需要求得[a, b]
区间范围的和,则可以用sum[b] - sum[a - 1]
求得。如下:
origin = [1, 2, 3, 4, 5]
sum = [1, 3, 6, 10, 15]
如果我要快速求得
origin
下标是[2, 4]
之间的值的和,那我可以直接用sum
数组的sum[4] - sum[1] = 15 - 3 = 12
获得 -
需要注意的是
- 如果区间左侧下标为
0
时,注意不要越界(可以在初始化sum
时,就预留第一位为0
来避免越界,当然具体求解[a, b]
区间时,也会变为sum[b + 1] - sum[a]
) - 在实际解题的时候,可能不需要真的
new
出这个sum
数组,而是用一个变量来累计循环数组的每项和而计算。就像今天的这道题一样。具体如何求解还是需要看题目的需求
- 如果区间左侧下标为
如果需要做一个经典的题来练习这个算法,可以参考这个:560. 和为K的子数组
正式分析
我们继续使用上面分析使用的各项定义来具体分析此题
以 示例一 为例: nums = [23, 2, 4, 6, 7]
, k = 6
为了符合题目要求: 令整数 x
符合 x = n * k
,那么必须是 nums
前缀和可以被 k
整除
那么我们可以由 求前缀和
改为 求前缀余数和
, 如果前缀余数和为 0
,则代表在当前这个区间中,存在一个子区间满足 令整数 x
符合 x = n * k
而我们可以定义一个变量存放每次与 6
取余得到的余数,然后与循环值相加,如果再次得到的余数为 0
,则代表满足了 令整数 x
符合 x = n * k
条件:
====这里有点写错了,正在修改
具体代码
function checkSubarraySum(nums: number[], k: number): boolean {
if (nums.length < 2) return false
const map = new Map()
map.set(0, -1)
const length = nums.length
let remain = 0
for (let i = 0; i < length; i++) {
remain = (remain + nums[i]) % k
if (map.has(remain)) {
const prevIndex = map.get(remain)
if (i - prevIndex >= 2) return true
} else {
map.set(remain, i)
}
}
return false
};
TS AC,执行用时:128ms
, 在所有 TypeScript
提交中击败了 33.33%
的用户
TS AC中击败 100% 用户的提交,目前执行下来用时 180ms
,估计力扣增加了测试用例导致更简单的算法耗时比之前提交的复杂的算法耗时要久,这对后期用户提交并不友好
问题升级
本题用到了一位数组的前缀和,那么自然也有二维数组前缀和
可以参考此题:304. 二维区域和检索 - 矩阵不可变
各大公司对前缀和的考察还是比较多的
最后
如果我在哪里写的有问题,欢迎指出,共同进步,谢谢阅读~
标签:前缀,nums,sum,整数,LeetCode,remain,数组,523,20210602 来源: https://blog.csdn.net/mxd26888/article/details/117485159