Skip to content

Commit 3447399

Browse files
committed
二刷316
1 parent 8e7da3c commit 3447399

File tree

4 files changed

+75
-27
lines changed

4 files changed

+75
-27
lines changed

docs/0316-remove-duplicate-letters.adoc

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
[#0316-remove-duplicate-letters]
2-
= 316. Remove Duplicate Letters
2+
= 316. 去除重复字母
33

4-
{leetcode}/problems/remove-duplicate-letters/[LeetCode - Remove Duplicate Letters^]
4+
https://leetcode.cn/problems/remove-duplicate-letters/[LeetCode - 316. 去除重复字母 ^]
55

6-
Given a string which contains only lowercase letters, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
6+
给你一个字符串 `s`,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 *返回结果的字典序最小*(要求不能打乱其他字符的相对位置)。
77

8-
*Example 1:*
8+
*示例 1:*
99

10-
[subs="verbatim,quotes,macros"]
11-
----
12-
*Input:* `"bcabc"`
13-
*Output:* `"abc"`
14-
----
10+
....
11+
输入:s = "bcabc"
12+
输出:"abc"
13+
....
1514

16-
*Example 2:*
15+
*示例 2:*
1716

18-
[subs="verbatim,quotes,macros"]
19-
----
20-
*Input:* `"cbacdcbc"`
21-
*Output:* `"acdb"`
22-
----
17+
....
18+
输入:s = "cbacdcbc"
19+
输出:"acdb"
20+
....
21+
22+
*提示:*
23+
24+
* `1 \<= s.length \<= 10^4^`
25+
* `s` 由小写英文字母组成
2326
2427
== 思路分析
2528

@@ -37,14 +40,14 @@ include::{sourcedir}/_0316_RemoveDuplicateLetters.java[tag=answer]
3740
----
3841
--
3942
40-
// 二刷::
41-
// +
42-
// --
43-
// [{java_src_attr}]
44-
// ----
45-
// include::{sourcedir}/_0316_RemoveDuplicateLetters_2.java[tag=answer]
46-
// ----
47-
// --
43+
二刷::
44+
+
45+
--
46+
[{java_src_attr}]
47+
----
48+
include::{sourcedir}/_0316_RemoveDuplicateLetters_2.java[tag=answer]
49+
----
50+
--
4851
====
4952

5053

logbook/202503.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ endif::[]
6060
|{doc_base_url}/0076-minimum-window-substring.adoc[题解]
6161
|⭕️ 滑动窗口,一定注意细节的处理。
6262

63+
|{counter:codes2503}
64+
|{leetcode_base_url}/remove-duplicate-letters/[316. Remove Duplicate Letters^]
65+
|{doc_base_url}/0316-remove-duplicate-letters.adoc[题解]
66+
|❌ 完全想不到单调栈!
67+
6368
|===
6469

6570
截止目前,本轮练习一共完成 {codes2503} 道题。

src/main/java/com/diguage/algo/leetcode/_0316_RemoveDuplicateLetters.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package com.diguage.algo.leetcode;
22

3-
import java.util.ArrayList;
4-
import java.util.List;
5-
63
public class _0316_RemoveDuplicateLetters {
74
// tag::answer[]
85
/**
96
* @author D瓜哥 · https://www.diguage.com
10-
* @since 2020-01-28 15:16
7+
* @since 2024-08-16 19:08
118
*/
129
public String removeDuplicateLetters(String s) {
1310
if (s == null || s.isEmpty()) {
@@ -27,9 +24,11 @@ public String removeDuplicateLetters(String s) {
2724
}
2825
while (!chars.isEmpty() && chars.charAt(chars.length() - 1) > c) {
2926
int lastIdx = chars.charAt(chars.length() - 1) - 'a';
27+
// 如果已选中的最后一个字符,在后续字符串中没有了,就不能再删除了。
3028
if (count[lastIdx] == 0) {
3129
break;
3230
}
31+
// 否则,删除掉。后面还可以再加进来
3332
chars.deleteCharAt(chars.length() - 1);
3433
visited[lastIdx] = false;
3534
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _0316_RemoveDuplicateLetters_2 {
4+
// tag::answer[]
5+
/**
6+
* @author D瓜哥 · https://www.diguage.com
7+
* @since 2025-03-24 20:39:51
8+
*/
9+
public String removeDuplicateLetters(String s) {
10+
char[] chars = s.toCharArray();
11+
int[] count = new int[26];
12+
for (char c : chars) {
13+
count[c - 'a']++;
14+
}
15+
boolean[] added = new boolean[26];
16+
// result 就是一个“单调栈”
17+
StringBuilder result = new StringBuilder();
18+
for (char c : chars) {
19+
int idx = c - 'a';
20+
count[idx]--;
21+
if (added[idx]) {
22+
continue;
23+
}
24+
// 类似单调栈的操作:单调递增栈,遇到小的,则大的出栈
25+
while (!result.isEmpty() && result.charAt(result.length() - 1) > c) {
26+
int lastCharIdx = result.charAt(result.length() - 1) - 'a';
27+
// 如果 result 最后一个字符后续不再出现,则必须保留了。
28+
if (count[lastCharIdx] == 0) {
29+
break;
30+
}
31+
// 否则,删除。后续再遇到了再添加
32+
result.deleteCharAt(result.length() - 1);
33+
added[lastCharIdx] = false;
34+
}
35+
result.append(c);
36+
added[idx] = true;
37+
}
38+
return result.toString();
39+
}
40+
// end::answer[]
41+
}

0 commit comments

Comments
 (0)