最大子串的长度加起来为 S
Posted
技术标签:
【中文标题】最大子串的长度加起来为 S【英文标题】:Length of largest substring adds up to S 【发布时间】:2016-06-14 13:55:00 【问题描述】:我在一次采访中被问到以下问题,我无法给出最佳答案。
问题:编写一个程序,找出总和为 S 的最大连续子数组的长度。给定一个可变大小的数组和一个整数。
输入: 1. 一个可变大小的数组,它只能有 -1, 0, 1 个元素。
示例:A[] = 1, 0, 0, 1, -1, 1, 1, 1, 1
-
一个整数S,
示例:S = 4
输出:8
解释:A 的最大连续子数组加起来 S=4:1, 0, 0, 1, -1, 1, 1, 1 或 0, 0, 1, -1, 1 , 1, 1, 1
约束:应该在 O(N) 内完成
我已经解决了问题,但无法满足时间复杂度。任何人都可以提供可以在 O(N) 中解决此问题的解决方案。
PS:我提出的问题没有版权问题。
【问题讨论】:
子数组是否连续? @TamasIonut 它是一个连续的子数组。 【参考方案1】:遍历将总和存储到变量中当前元素的数组。对于每个总和值,将其放入 O(1) 中的哈希表中(如果它不存在),映射到它出现的索引。
但是,在每次插入之前,检查哈希表是否已经包含 current_sum - S。如果包含,则表示子数组 [previous_index+1..current_index] 有 sum S。
即使数组包含 -1, 0, 1 以外的元素,这也有效。
这是一个 Python 代码示例:
def solve(A, S):
table = 0: 0
answer = None
total = 0
for i, x in enumerate(A):
total += x
if total - S in table:
candidate = (table[total-S], i)
if answer is None or candidate[1] - candidate[0] > answer[1] - answer[0]:
answer = candidate
if total not in table:
table[total] = i+1
return answer
print solve([-1, 0, 1, 1, 1, 1, 1, 0, 0, 1], 4)
【讨论】:
这段代码输出(4,15),意思是答案长度是15? @shole 不,这意味着从索引 4 开始到索引 15 结束的字符串是最长的。答案是,实际上 15-4+1 = 12。 @JuanLopes 似乎您的解决方案不适用于所有场景。这是一个求解([-1, 0, 1, 1, 1, 1, 1, 0, 0, 1], 4)。 @ikis 你是对的,但我认为 0 是一种特殊情况,因为它是唯一可以从空数组中实现的值。因此,只需在开始时将 0:0 放在表中即可。 (已编辑)【参考方案2】:如果只有 -1、0 和 1 这三个值,那么您可以通过计算 -1、0 和 1 的值的数量来解决问题。然后应用公式。大意是:
取所有的 0。 确保您有足够的 1(用于正数,-1 用于负数)。 如果不是,则出错。 然后选择正确数量的 1s/-1s,这样你就可以用完所有的“其他值”最后一点故意有点模糊(你可以通过一些例子来思考)。
关键点是使用三个值,您可以填充这三个值。然后你可以使用一些规则来获得最长的合适的总和。
【讨论】:
【参考方案3】:算法概述:
-
将 Lo[x] 定义为 总和为 x 的最长前缀和的长度
将 Sh[x] 定义为 总和为 x 的最短前缀和的长度
Ans = max(Lo[x+S] - Sh[x]) for all x,可以通过循环数组一次找到
Lo[]
和 Sh[]
的内存大小都是 O(n)
,因为所有元素都在 -1,0,1 中
要处理负和,其中一种方法是将范围-n..n
映射到0..2n
以便索引x
可以表示(两个数组的大小因此为O(2n)
= O(n)
)
要计算前缀和,只需遍历数组一次,然后更新数组,Lo[]
和 Sh[]
都可以在 O(n)
中计算
【讨论】:
以上是关于最大子串的长度加起来为 S的主要内容,如果未能解决你的问题,请参考以下文章
2022-12-24:给定一个字符串s,其中都是英文小写字母, 如果s中的子串含有的每种字符都是偶数个, 那么这样的子串就是达标子串,子串要求是连续串。 返回s中达标子串的最大长度。 1 <= s的长