最短的子串,其中A和B的计数差异最大

时间:2017-11-12 01:33:26

标签: python string algorithm

我遇到了一个问题,要求从左边找到最短的子字符串,其字符数最大。我们保证字符串只包含两个字符,比如'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 个答案:

答案 0 :(得分: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)的结果总是与数组数的绝对差值相同&#34;包围&#34;这个word。示例:对于&#34; ABA&#34; calc()将返回1并且如果您查看&#34; ABA&#34;的两次出现的封闭数字,则它们是0和1(结果1)以及1和2(也是结果1)。< / p>

因此,给定字符串的calc()的最大可能值(这是所需的最大差值)是数组极值的绝对差值,只有当具有这些极值的数组索引为用来&#34;附上&#34;子串。

寻找最短的极值距离

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

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