【发布时间】:2020-01-18 04:37:45
【问题描述】:
计算字符串中唯一子串总数的有效方法是什么
【问题讨论】:
标签: django
计算字符串中唯一子串总数的有效方法是什么
【问题讨论】:
标签: django
如果我们看看下面的双循环:
for i in range(l):
for j in range(1,l-i+1):
mylist.append(string[i:j+i])
然后就很清楚为什么您的解决方案在某些测试用例中以Runtime Error 终止 - 循环中的空间复杂度太高了! mylist 中的元素数量与 n2 成正比,其中n 是原始字符串的长度。根据任务描述,字符串长度可以接近10^6个字符,你的mylist大小可以分别变成10^12。
更糟糕的是,mylist 的元素不仅仅是单个字符,而是原始字符串的子字符串。因此,空间复杂度实际上是 O(n3)。由于您的示例输入字符串的长度为5000,因此您将超过512MB,这是here 所述的最大允许阈值。
您必须意识到,您不需要任何mylist 来计算 Stuart 和 Kevin 的分数。相反,您可以直接在循环中计算他们的分数。为什么?因为它已经生成了原始字符串的所有子字符串,其中string[i] 是给定子字符串的第一个字符。然后,如果它是元音,则增加 Kevin 的分数,否则 - Stuart 的分数:
stuart=0
kevin=0
for i in range(l):
for j in range(1,l-i+1):
if string[i] in vowel:
kevin += 1
else:
stuart += 1
在上一段中,我们做了很大的改进,因为Runtime Error消失了,但是解决方案对于一些测试用例仍然会超时,因为它的时间复杂度仍然太高 - O(n2).
要改进它,你必须意识到以string[i] 开头的子字符串的数量是len(string) - i。因此,不需要内部循环,原始双循环可以简化为 O(n) 时间复杂度解决方案:
stuart = 0
kevin = 0
for i in range(l):
if string[i] in vowel:
kevin += (l - i)
else:
stuart += (l - i)
def minion_game(string):
l = len(string)
vowel=['A','E','I','O','U']
stuart = 0
kevin = 0
for i in range(l):
if string[i] in vowel:
kevin += (l - i)
else:
stuart += (l - i)
if kevin > stuart:
print(f'Kevin {kevin:d}')
elif stuart > kevin:
print(f'Stuart {stuart:d}')
else:
print('Draw')
【讨论】: