【发布时间】:2022-01-05 22:48:20
【问题描述】:
我遇到了以下问题:
给定一个整数数组arr、一个正整数k和一个整数s,你的任务是找到长度不大于k的非空连续子数组的数量,并且总和等于s。
对于arr = [1, 2, 4, -1, 6, 1]、k = 3 和s = 6,输出应为solution(arr, k, s) = 3。
- 长度为
1的连续子数组中有1子数组 总和等于s = 6,它是[6], - 长度为
2的连续子数组中有1子数组 总和等于s = 6,它是[2, 4], - 长度为
3的连续子数组中有1子数组 总和等于s = 6,它是[-1, 6, 1]。
请注意,子数组[1, 2, 4, -1] 的总和也会等于s,但它的长度大于k,因此不适用。
所以答案是3。
以下是我在 Python 中的尝试。我的想法是将每个前缀总和出现的索引存储在字典中。例如,如果前缀和 6 出现在索引 1 和 3 处,则字典中的条目将是 6:[1, 3]。然后在每一步我们都可以检查目标和s是否遇到(if curr - s in d:)以及子数组的范围。
这通过了 10/15 的测试用例,但超过了剩余隐藏用例的时间限制。如果有人有优化算法,我将不胜感激。
import collections
def solution(arr, k, s):
res = 0
curr = 0
d = collections.defaultdict(list)
d[0].append(-1)
for i, num in enumerate(arr):
curr += num
if curr - s in d:
for idx in d[curr-s]:
if i - idx <= k:
res += 1
d[curr].append(i)
return res
【问题讨论】:
-
这个循环是问题所在:
for idx in d[curr-s]:,您可以通过对存储在字典中的索引进行二进制搜索来消除它
标签: arrays algorithm cumulative-sum