我遇到了一个问题,要求从左边找到最短的子字符串,其字符数最大。我们保证字符串只包含两个字符,比如'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)。 我将如何提高该计划的效率?可能有更有效和更快速的方法来解决这个问题。任何提高效率和提出改进算法的帮助都会非常有帮助。谢谢!
答案 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)
的结果总是与数组数的绝对差值相同"包围"这个word
。示例:对于" ABA" calc()
将返回1并且如果您查看&#34; ABA&#34;的两次出现的封闭数字,则它们是0和1(结果1)以及1和2(也是结果1)。< / p>
因此,给定字符串的calc()
的最大可能值(这是所需的最大差值)是数组极值的绝对差值,只有当具有这些极值的数组索引为用来&#34;附上&#34;子串。
寻找最短的极值距离
假设最大和最小点现在包含在两个有序列表l1
和l2
中(从最小到最大索引号),则进一步的算法如下:
l1[0] < l2[0]
,否则交换l1
和l2
(l1[0], l2[0], l2[0] - l1[0])
作为可能的结果候选人
如果你之前没有遇到过更好的候选人。l1
删除第一个元素。如果l1
为空则现在结束循环。