📅  最后修改于: 2023-12-03 15:09:20.997000             🧑  作者: Mango
给定一个字符串,将其旋转任意次后,得到的字符串中字典序最小的字符串。
例如,给定字符串 "cab",将其旋转得到 "abc","bca","cab",其中字典序最小的是 "abc"。
本题属于字符串算法中的经典问题,常用于比较两个字符串之间的大小关系。
为了求得字典序最小的字符串,我们需要考虑从头至尾扫描字符串,找到可以旋转的位置。
具体地,我们可以用两个指针分别从字符串的首尾遍历,直到它们相遇。我们假设当前这一对指针所指向的字符分别为 s[i] 和 s[j]。
如果 s[i] < s[j],那么我们可以确定现在的旋转点不可能在 [j+1, n-1] 这个区间内,因为如果旋转点在这个区间内,那么 s[i] 必定比旋转点右侧的字符都要大,而 s[j] 则必定比旋转点左侧的字符都要小,这个时候就矛盾了。
因此,我们可以将 i 加上 1,然后继续遍历。反之,如果 s[i] > s[j],那么我们可以确定现在的旋转点不可能在 [i, j-1] 这个区间内。
如果这个时候我们找到了旋转点,那么答案就是旋转点左侧的字符串加上旋转点右侧的字符串。
如果没有找到旋转点,那么原字符串就是已经是排序后的字符串,我们可以直接返回该字符串。
代码如下:
def get_min_rotation(s: str) -> str:
n = len(s)
i, j = 0, n-1
while i < j:
if s[i] < s[j]:
j -= 1
elif s[i] > s[j]:
i += 1
else:
k, l = i+1, j-1
while k <= l and s[k] == s[l]:
k += 1
l -= 1
if k > l or s[k] < s[l]:
j -= 1
else:
i += 1
return s[i:] + s[:i]
该算法的时间复杂度为 O(n),其中 n 表示字符串的长度。因为在最坏情况下需要遍历一遍字符串。