使用“高度数组”可以很容易地回答这个问题O(n)
,表示 1 的数量相对于 0 的数量。就像我在链接问题中的回答一样。
现在,我们不再关注原始数组,而是关注由 heights 索引的两个数组,一个将包含找到高度的最小索引,另一个将包含找到高度的最大索引。由于我们不想要负索引,我们可以将所有内容向上移动,使得最小高度为 0。
因此,对于示例案例(我在最后添加了两个 1 以表明我的观点):
1110000011010000011111
数组高度可视化
/\
/ \
/ \
\ /\/\ /
\/ \ /
\ /
\ /
\/
(最低高度 = -5)
移位高度数组:
[5, 6, 7, 8, 7, 6, 5, 4, 3, 4, 5, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3]
身高:0 1 2 3 4 5 6 7 8
first_view = [17,16,15, 8, 7, 0, 1, 2, 3]
last_view = [17,18,19,20,21,22, 5, 4, 3]
请注意,我们有 22 个数字和 23 个不同的索引,0-22,代表数字之间的 23 个空格并填充数字
我们first_view
可以last_view
在O(n)
.
现在,对于 中的每个高度first_view
,我们只需要检查 中每个较大的高度last_view
,并取与索引相差最大的first_view
索引。例如,从高度 0 开始,较大高度的索引最大值为 22。因此,从索引 17+1 开始的最长子字符串将在索引 22 处结束。
要查找last_view
数组的最大索引,可以将其转换为右侧的最大值O(n)
:
last_view_max = [22,22,22,22,22,22, 5, 4, 3]
所以找到答案只是简单地减去first_view
,last_view_max
first_view = [17,16,15, 8, 7, 0, 1, 2, 3]
last_view_max = [22,22,22,22,22,22, 5, 4, 3]
结果 = [ 5, 6, 7,14,15,22, 4, 2, 0]
并取最大值(再次在 中O(n)
),即 22,从起始索引 0 到结束索引 22,即整个字符串。=D
正确性证明:
假设最大子字符串从 index 开始,在 indexi
结束j
。如果 index 处的高度与 indexi
处的高度相同k<i
,那么k..j
将是一个更长的子字符串,仍然满足要求。因此,考虑每个高度的第一个索引就足够了。类似地对于最后一个索引。