📌  相关文章
📜  字典最小的旋转序列 |设置 2(1)

📅  最后修改于: 2023-12-03 15:09:20.997000             🧑  作者: Mango

字典最小的旋转序列 |设置 2

简介

给定一个字符串,将其旋转任意次后,得到的字符串中字典序最小的字符串。

例如,给定字符串 "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 表示字符串的长度。因为在最坏情况下需要遍历一遍字符串。

参考资料
  1. LC154. Find Minimum in Rotated Sorted Array II

  2. 算法基础课 第八章 贪心 - 最小表示法