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() 的最大可能值(这是所需的最大差值)是数组编号的极值的绝对差,只有当具有这些极值的数组索引用于“包含”子字符串。

寻找最短极值距离

假设最大和最小点现在包含在两个有序列表l1l2(从最小到最大索引号)中,进一步的算法如下:

(循环开始) 确保l1[0] < l2[0],否则交换l1l2 记住(l1[0], l2[0], l2[0] - l1[0])作为可能的候选结果 如果您之前没有遇到过更好的候选人。 从l1 中删除第一个元素。如果l1 为空,则结束循环。 回到循环开始。

【讨论】:

有趣。您能否解释一下您是如何提出这种方法的? Ans 能否请您解释一下为什么这种方法总是有效的? @therealdev A 和 B 的顺序在某种程度上看起来像是对函数上下波动的描述,我无法解释为什么我会这样看。现在在答案中添加了它为什么起作用的解释。

以上是关于A 和 B 的计数差异最大的最短子串的主要内容,如果未能解决你的问题,请参考以下文章

和至少为K的最短子数组

2021-08-30:给定两个字符串str1和str2,在str1中寻找一个最短子串,能包含str2的所有字符,字符顺序无所谓,str1的这个最短子串也可以包含多余的字符。返回这个最短包含子串。(代码

[算法]需要排序的最短子数组长度

算法/编程练习:和至少为K的最短子数组

LeetCode 862. 和至少为 K 的最短子数组

从一道算法面试题看我国信息科技的原创性不足:查找包含所有元素的最短子数组