Skip to content

Commit e0f35e6

Browse files
committed
✨feat: add 899
1 parent 54216c4 commit e0f35e6

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

Index/最小表示法.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| 题目 | 题解 | 难度 | 推荐指数 |
2+
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
3+
| [899. 有序队列](https://leetcode.cn/problems/orderly-queue/) | [LeetCode 题解链接](https://leetcode.cn/problems/orderly-queue/solution/by-ac_oier-443m/) | 困难 | 🤩🤩🤩🤩🤩 |
4+

Index/构造.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [324. 摆动排序 II](https://leetcode.cn/problems/wiggle-sort-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/wiggle-sort-ii/solution/by-ac_oier-22bq/) | 中等 | 🤩🤩🤩🤩 |
44
| [406. 根据身高重建队列](https://leetcode.cn/problems/queue-reconstruction-by-height/) | [LeetCode 题解链接](https://leetcode.cn/problems/queue-reconstruction-by-height/solution/by-ac_oier-fda2/) | 中等 | 🤩🤩🤩🤩 |
5+
| [899. 有序队列](https://leetcode.cn/problems/orderly-queue/) | [LeetCode 题解链接](https://leetcode.cn/problems/orderly-queue/solution/by-ac_oier-443m/) | 困难 | 🤩🤩🤩 |
56
| [942. 增减字符串匹配](https://leetcode.cn/problems/di-string-match/) | [LeetCode 题解链接](https://leetcode.cn/problems/di-string-match/solution/by-ac_oier-pvjk/) | 简单 | 🤩🤩🤩🤩🤩 |
67
| [961. 在长度 2N 的数组中找出重复 N 次的元素](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/solution/by-ac_oier-bslq/) | 简单 | 🤩🤩🤩🤩 |
78
| [1260. 二维网格迁移](https://leetcode.cn/problems/shift-2d-grid/) | [LeetCode 题解链接](https://leetcode.cn/problems/shift-2d-grid/solution/by-ac_oier-1blt/) | 简单 | 🤩🤩🤩🤩 |

LeetCode/621-630/622. 设计循环队列(中等).md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
这是 LeetCode 上的 **[622. 设计循环队列](https://leetcode.cn/problems/design-circular-queue/solution/by-ac_oier-y11p/)** ,难度为 **中等**
44

5-
Tag : 「设计数据结构」
5+
Tag : 「设计数据结构」、「队列」
66

77

88

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[899. 有序队列](https://leetcode.cn/problems/orderly-queue/solution/by-ac_oier-443m/)** ,难度为 **困难**
4+
5+
Tag : 「构造」、「最小表示法」
6+
7+
8+
9+
给定一个字符串 `s` 和一个整数 `k` 。你可以从 `s` 的前 `k` 个字母中选择一个,并把它加到字符串的末尾。
10+
11+
返回 在应用上述步骤的任意数量的移动后,字典上最小的字符串 。
12+
13+
示例 1:
14+
```
15+
输入:s = "cba", k = 1
16+
17+
输出:"acb"
18+
19+
解释:
20+
在第一步中,我们将第一个字符(“c”)移动到最后,获得字符串 “bac”。
21+
在第二步中,我们将第一个字符(“b”)移动到最后,获得最终结果 “acb”。
22+
```
23+
示例 2:
24+
```
25+
输入:s = "baaca", k = 3
26+
27+
输出:"aaabc"
28+
29+
解释:
30+
在第一步中,我们将第一个字符(“b”)移动到最后,获得字符串 “aacab”。
31+
在第二步中,我们将第三个字符(“c”)移动到最后,获得最终结果 “aaabc”。
32+
```
33+
34+
提示:
35+
* $1 <= k <= S.length <= 1000$
36+
* `s` 只由小写字母组成。
37+
38+
---
39+
40+
### 最小表示法
41+
42+
当 $k > 1$ 时,我们能够构造出任意的字符串方案,因此当 $k > 1$ 时,我们可以直接通过对字符串排序来得到答案,复杂度为 $O(n\log{n})$。
43+
44+
当 $k = 1$ 时,我们共有 $n$ 种候选方案(将字符串 `s` 看作一个首尾相接的循环字符串,共有 $n$ 个起点可枚举),枚举过程中需要与当前最优的方案进行比较,比较复杂度为 $O(n)$,因此整体复杂度为 $O(n^2)$。
45+
46+
上述的做法已经可以通过本题,可以看出瓶颈在于对 $k = 1$ 的处理。
47+
48+
而实际上,对于给定字符串 `s`,求其循环同构的所有方案中字典序最小的方案,可以使用「最小表示法」来做,复杂度为 $O(n)$。
49+
50+
最小表示法将「方案比较」与「构造更优方案」进行结合:假设我们当前有两字符串 `a``b` 需要进行比较,其均为原串 `s` 的循环同构具体方案。假设 `a``b` 分别对应了原串下标为 `i``j` 的具体方案,且假设两字符串前 $k$ 个字符均相同。当两字符串第一个不同的字符大小关系为 $cs[i + k] > cs[j + k]$ 时,可以发现以下标范围 $[i, i + k]$ 作为起点的新方案必然不可能比字符串 `b` 更优,因此我们可以直接从 $i + k + 1$ 位置构造新的更优方案,并与 `b` 再次比较。而 $cs[i + k] < cs[j + k]$ 的分析同理。
51+
52+
Java 代码:
53+
```Java
54+
class Solution {
55+
public String orderlyQueue(String s, int _k) {
56+
char[] cs = s.toCharArray();
57+
if (_k == 1) {
58+
int i = 0, j = 1, k = 0, n = cs.length;
59+
while (i < n && j < n && k < n) {
60+
char a = cs[(i + k) % n], b = cs[(j + k) % n];
61+
if (a == b) k++;
62+
else {
63+
if (a > b) i += k + 1;
64+
else j += k + 1;
65+
if (i == j) i++;
66+
k = 0;
67+
}
68+
}
69+
i = Math.min(i, j);
70+
return s.substring(i) + s.substring(0, i);
71+
} else {
72+
Arrays.sort(cs);
73+
return String.valueOf(cs);
74+
}
75+
}
76+
}
77+
```
78+
TypeScript 代码:
79+
```TypeScript
80+
function orderlyQueue(s: string, _k: number): string {
81+
if (_k == 1) {
82+
let i = 0, j = 1, k = 0, n = s.length
83+
while (i < n && j < n && k < n) {
84+
const a = s[(i + k) % n], b = s[(j + k) % n]
85+
if (a == b) k++;
86+
else {
87+
if (a > b) i += k + 1
88+
else j += k + 1
89+
if (i == j) i++
90+
k = 0
91+
}
92+
}
93+
i = Math.min(i, j)
94+
return s.substring(i) + s.substring(0, i)
95+
} else {
96+
return [...s].sort().join('');
97+
}
98+
};
99+
```
100+
* 时间复杂度:当 $k = 1$ 时,复杂度为 $O(n)$;当 $k > 1$ 时,复杂度为 $O(n\log{n})$
101+
* 空间复杂度:当 $k > 1$ 时,需要使用额外的排序空间 $O(n\log{n})$
102+
103+
---
104+
105+
### 最后
106+
107+
这是我们「刷穿 LeetCode」系列文章的第 `No.899` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
108+
109+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
110+
111+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
112+
113+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
114+

0 commit comments

Comments
 (0)