s = raw_input()
n = len(s)
el = []
z = n - 1
while z >= 0:
x = s[z:] + s[:z]
z = z - 1
el.append(x)
print max(el)
代码工作正常但效率很低。是否有更有效的方法来解决问题?
答案 0 :(得分:0)
您可以使用suffix arrays在线性时间内解决此问题。给定输入字符串s
,构造加倍的字符串ss
。使用线性时间算法构造ss
的后缀数组。后缀数组按字典顺序保存ss
的充分索引。最后,向后扫描后缀数组,跳过ss
下半部分的索引。从ss
的上半部开始的按字典顺序排列的最大后缀可以被修整为s
的旋转度。
该问题与here中描述的问题类似,不同之处在于该问题与按字典顺序的最小旋转有关,并且您希望按字典顺序的最大旋转。
上面链接的文章提到了一些可用于后缀数组构造的算法。在这里,我不会对此部分进行明确的解释,但是对于Python实现,请参见此article。
因此,假设您已对后缀数组算法create_suffix_array(s: str) -> [int]
进行了某种实现,以使create_suffix_array(s)
以字典顺序返回足够的索引序列,则可以将该算法应用于您的问题,如下所示:
def rotate(s: str, n: int) -> str:
return s[n:] + s[:n]
def solve(s: str) -> str:
indices: [int] = create_suffix_array(s + s)
is_first_half = lambda i: i < len(s)
best_index = next(filter(is_first_half, reversed(indices)))
return rotate(s, best_index)
让s
为长度为n
的字符串。令i
为ss
的字典上最大后缀的索引,该后缀始于ss
的上半部分。 ss
定义的i
后缀为s[i,n-1]s
。
考虑j
中的任何[0,n-1]
。然后,由ss
定义的j
后缀不能大于s[i,n-1]s
。 s[j,n-1]s <= s[i,n-1]s
这样。然后得出结论,这些充分的任意两个相等大小的前缀具有相同的顺序。特别是s[j,n-1]s[0,j-1] <= s[i,n-1]s[0,i-1]
,因为两者都是两个n
大小的前缀。
因此,s[i,n-1]s[0,i-1]
是s
在字典上最大的旋转。