899. 有序队列
本文最后更新于 2022年8月11日 上午
思路
这是一道看似 Hard,实则想出方法就 Easy 的题。
当 \(k = 1\)
时,变成找字典序最小的循环子串问题。
当 \(k > 1\)
时,经过任意步移动一定可以将字符串 \(S\) 变成升序字符串。
证明
当 \(k = 2\)
时,类比插入排序,可以假装将 \(S[0]\)
拿出,不停地将 \(S[1]\)
移动到字符串末尾,就好像字符串在旋转。转到合适的位置时,将 \(s[0]\)
插入字符串。经过若干次操作后,就能对字符串完成排序。
flowchart LR
0
1 --> n-1
n-1 --> n-2
n-2 -..-> 3
3 --> 2
2 --> 1
实现
1 |
|
\(k = 1\) 时,时间复杂度为 \(O(n^2)\),
\(k > 1\) 时,时间复杂度为 \(O(n \log n)\)
\(k = 1\) 情况的优化
\(k = 1\) 其实就是求字符串的最小表示,可以将时间复杂度优化到
\(O(n)\)。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36function minimumRepresentation(s: string): number {
let len: number = 0, i: number = 0, j: number = 1
const n: number = s.length
while (len < n && i < n && j < n) {
const a: string = s[(i + len) % n]
const b: string = s[(j + len) % n]
if (a == b) {
++len
} else {
if (a > b) {
i = i + len + 1
}
else {
j = j + len + 1
}
len = 0
if (i == j) {
++i
}
}
}
return Math.min(i, j)
}
function orderlyQueue(s: string, k: number): string {
if(s.length === 1) {
return s
}
if(k == 1) {
const index = minimumRepresentation(s)
return s.substring(index) + s.substring(0, index)
}
else {
return [...s].sort().join('')
}
}