899. Orderly Queue

A string S of lowercase letters is given.  Then, we may make any number of moves.

In each move, we choose one of the first K letters (starting from the left), remove it, and place it at the end of the string.

Return the lexicographically smallest string we could have after any number of moves.

Example 1:

Input: S = "cba", K = 1
Output: "acb"
Explanation:
In the first move, we move the 1st character ("c") to the end, obtaining the string "bac".
In the second move, we move the 1st character ("b") to the end, obtaining the final result "acb".

Example 2:

Input: S = "baaca", K = 3
Output: "aaabc"
Explanation:
In the first move, we move the 1st character ("b") to the end, obtaining the string "aacab".
In the second move, we move the 3rd character ("c") to the end, obtaining the final result "aaabc".

Note:

  1. 1 <= K <= S.length <= 1000
  2. S consists of lowercase letters only.

这道题给了我们一个只有小写字母的字符串,说是每次可以把前K个字母中的任意一个移动到末尾,让我们返回可以变换成的字母顺序最小的字符串。刚开始看到的时候,博主感觉就是一个 BFS 遍历,对于每一个状态,都生成K个新的状态,然后将没有遍历过的加入 queue 中去遍历,然后维护一个全局最小的 res 即可,写完之后拿到 OJ 中去测试了,结果跪了,Time Limit Exceeded!心想着,还能怎么优化呢?一逛论坛后发现,这道题还是真是有 trick 的,如果不仔细想,感觉不太容易想到。正确的思路其实是跟K值有关的,若 K=1,其实只有K中不同的情况,我们可以都生成,然后比较出其中最小的那个返回即可。关键是 K>1 的时候,比较 tricky,其实是可以转换成有序的,即相当于直接对S串进行排序即可。我们就拿 S=”53214”, K=2 来举例吧,转换过程如下所示:

5 3 2 1 4
3 2 1 4 5
3 1 4 5 2
1 4 5 2 3
1 5 2 3 4
1 2 3 4 5

虽然不知道如何严格的证明当 K>1 时,一定能转成有序的排序,但是博主试了几个例子,都是可以的,论坛上说是一种类似于冒泡排序 Bubble Sort 的过程。若有哪位看官大神们知道如何证明,请务必留言告诉博主哈,参见代码如下:

class Solution {
public:
    string orderlyQueue(string S, int K) {
        if (K > 1) {
            sort(S.begin(), S.end());
            return S;
        }
        string res = S;
        for (int i = 0; i < S.size(); ++i) {
            res = min(res, S.substr(i) + S.substr(0, i));
        }
        return res;
    }
};

讨论:微信公众号粉丝 YF 童鞋提供了一种不严格的证明过程。只要证明 k=2 能将任意字符串转为有序的,那么对于任意 k>1 的情况都是成立的。对于任意顺序,我们都可以现将最小的数字移动到末尾,形成 xxxxx1 这种类型的,然后一定有办法将第二小的数字移动到末尾,变成 xxxx12,以此类推类推,可以将所有数字按顺序移动到末尾,形成类似冒泡排序的操作,拿 871524 来举例:

  • 将1移动到末尾

    8 7 1 5 2 4
    7 1 5 2 4 8
    1 5 2 4 8 7
    5 2 4 8 7 1

  • 将2移动到末尾

    5 2 4 8 7 1
    5 4 8 7 1 2

  • 将4移动到末尾

    5 4 8 7 1 2
    5 8 7 1 2 4

  • 将5移动到末尾

    5 8 7 1 2 4
    8 7 1 2 4 5

  • 将7移动到末尾

    8 7 1 2 4 5
    8 1 2 4 5 7

  • 将8移动到末尾

    8 1 2 4 5 7
    1 2 4 5 7 8

Github 同步地址:

https://github.com/grandyang/leetcode/issues/899

参考资料:

https://leetcode.com/problems/orderly-queue/

https://leetcode.com/problems/orderly-queue/discuss/165862/Kgreater1-is-bubblesort

https://leetcode.com/problems/orderly-queue/discuss/165878/C%2B%2BJavaPython-Sort-String-or-Rotate-String

LeetCode All in One 题目讲解汇总(持续更新中…)


转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com

💰


微信打赏


Venmo 打赏

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,试运营期间前五十位可享受半价优惠~)

×

Help us with donation