A 和 B 的计数差异最大的最短子串
Posted
技术标签:
【中文标题】A 和 B 的计数差异最大的最短子串【英文标题】:Shortest Substring that has the maximum difference in counts of A and B 【发布时间】:2017-11-12 01:33:25 【问题描述】:我遇到了一个问题,要求从左侧找到其字符数差异最大的最短子字符串。我们保证字符串只包含两个字符,比如“A”和“B”。我们需要找到最短和最左边的子串,使得这个子串中 'A' 和 'B' 的计数之间的绝对差值最大化。
例如“BAABAABAABB”。在这种情况下,子字符串将是“AABAABAA”,子字符串从索引 1 开始并以 8 结束,因为 A 的计数为 6,B 为 2,差值为 4。所以,答案是 (1, 8),即子串的开始和结束索引。
我用 Python 编写了一个算法,可以通过以下方式做到这一点。
max_diff = 0
def calc(word):
return abs(word.count('A') - word.count('B'))
def get_window(word):
if len(word) == 1:
return (0, 0)
for start in range(len(word)-1):
for end in range(start+1, len(word)):
diff =calc(word[start:end+1])
if diff == max_diff:
return (start, end)
word = "BAABAABAABB"
for start in range(len(word)-1):
for end in range(start+1, len(word)):
max_diff = max(max_diff, calc(word[start:end+1]))
print get_window(word)
我认为这个解决方案的时间复杂度是 O(N^3)。 我将如何提高该程序的效率?可能有更有效和更快的方法来解决这个问题。任何提高效率和提出改进算法的帮助都会非常有帮助。谢谢!
【问题讨论】:
在更靠右的较短子串和靠左更远的较长子串之间进行选择,这被认为更可取? 总是选择最短的子串。如果有两个相同长度的子串,它们的差是最大差,选择最左边的子串。 【参考方案1】:它应该以这种方式工作:
创建第二个数组,表示字符“之间”的数字,例如 A 加一,B 减一。例如,这个数组看起来像
0 -1 0 1 0 1 2 1 2 3 2 1
B A A B A A B A A B B
在构建数组期间,记住值最小和最大的位置。如果有多个最大或最小点,则现在减少任务以找到最接近的最大和最小点。
为什么会这样?
很容易看出,calc(word)
的结果总是与“包围”这个word
的数组数字的绝对差值相同。示例:对于“ABA”calc()
将返回 1,如果您查看两次出现“ABA”的封闭数字,它们是 0 和 1(结果 1)以及 1 和 2(也是结果 1)。
因此,对于给定字符串,calc()
的最大可能值(这是所需的最大差值)是数组编号的极值的绝对差,只有当具有这些极值的数组索引用于“包含”子字符串。
寻找最短极值距离
假设最大和最小点现在包含在两个有序列表l1
和l2
(从最小到最大索引号)中,进一步的算法如下:
l1[0] < l2[0]
,否则交换l1
和l2
记住(l1[0], l2[0], l2[0] - l1[0])
作为可能的候选结果
如果您之前没有遇到过更好的候选人。
从l1
中删除第一个元素。如果l1
为空,则结束循环。
回到循环开始。
【讨论】:
有趣。您能否解释一下您是如何提出这种方法的? Ans 能否请您解释一下为什么这种方法总是有效的? @therealdev A 和 B 的顺序在某种程度上看起来像是对函数上下波动的描述,我无法解释为什么我会这样看。现在在答案中添加了它为什么起作用的解释。以上是关于A 和 B 的计数差异最大的最短子串的主要内容,如果未能解决你的问题,请参考以下文章
2021-08-30:给定两个字符串str1和str2,在str1中寻找一个最短子串,能包含str2的所有字符,字符顺序无所谓,str1的这个最短子串也可以包含多余的字符。返回这个最短包含子串。(代码