有没有办法在 O(n) 时间内打印字符串的所有子字符串?
Posted
技术标签:
【中文标题】有没有办法在 O(n) 时间内打印字符串的所有子字符串?【英文标题】:Is there a way to print all substrings of a string in O(n) time? 【发布时间】:2020-07-19 16:59:37 【问题描述】:我有一个输入 abcde
。我正在尝试输出如下内容:
a
ab
abc
abcd
abcde
b
bc
bcd
bcde
c
cd
cde
d
de
e
我无法编写没有嵌套循环的代码。我的问题是 O(n) 时间复杂度的问题的解决方案是什么?
我的代码如下:
s = "abcde"
for i in range(len(s)):
for x in range(i, len(s) + 1):
a = s[i:x]
if a != "": print(a)
【问题讨论】:
如果n
应该是输入的长度,那是不可能的。
顺序重要吗?
不,没关系
【参考方案1】:
有没有办法在
O(N)
时间打印字符串的所有子字符串?
不,没有。这在数学上是不可能的。
长度为N
的字符串有O(N^2)
子字符串。您不能在O(N)
时间打印O(N^2)
字符串。即使字符串全部(单独)O(1)
打印。 (他们不是。)
即使是并行性也无法将您带到O(N)
。如果(假设)有一个P > N
处理器来生成字符串,打印它们是一个您无法并行化的过程。
为了记录,可以以避免显式嵌套循环的方式对此进行编码。但这并没有改变比 O(N^3)
更好的解决方案的基本数学不可能性。
【讨论】:
【参考方案2】:让我们在没有嵌套循环的情况下执行此操作!
这是一个带有random
库的游戏,但执行时间与您的代码相似。
from random import randint
list1=[]
str1='abcde'
while len(list1)!=int(((len(str1)+1)*len(str1))//2):
i=randint(0,len(str1))
j=randint(0,len(str1))
i,j=max(i,j),min(i,j)
if i!=j:
a=str1[j:i]
if a not in list1:
list1.append(a)
print(a)
如果是字符串str1 = 'abcdef'
,则打印:
de
abcdef
cdef
abc
ef
d
c
abcd
b
abcde
def
bcde
f
bcdef
a
bcd
cd
e
ab
cde
bc
现在,如果您希望数据按照您指定的顺序,请使用sort
:
list1.sort()
【讨论】:
这不是所要求的O(N)
。它是O(N^3)
。没有O(N)
解决方案。
而且甚至不起作用。【参考方案3】:
如果您还打印子字符串,时间复杂度会上升到 O(N^3)
,因为每个子字符串的长度是 O(N)
,因此您将在 O(N)
时间内打印 O(N^2)
子字符串,每个时间复杂度都为整体复杂度的O(N^3)
。请参阅重复的Find all possible substring in fastest way。
附带说明一下,您可以通过将内部循环更改为从i+1
开始来避免空字符串检查,这是一个(非常)轻微的优化。
s = "abcde"
for i in range(len(s)):
for x in range(i+1, len(s)+1):
a = s[i:x]
print a
【讨论】:
这并不能解决 OP 问题。他不需要嵌套循环 没有嵌套循环的解决方案是可能的 这不是关于嵌套循环,而是关于时间复杂度。也许没有嵌套循环的解决方案是可能的,但不可能在少于O(N^3)
的时间内打印O(N^3)
个字符。
这个答案不相关,这不是问的!以上是关于有没有办法在 O(n) 时间内打印字符串的所有子字符串?的主要内容,如果未能解决你的问题,请参考以下文章
在 O(log(n)) 时间内从 std::set 中随机选择一个元素