Skip to content

Commit 408e5bd

Browse files
committed
feat: add solutions to lc problems: No.0316,1081
* No.0316.Remove Duplicate Letters * No.1081.Smallest Subsequence of Distinct Characters
1 parent 0b3bb25 commit 408e5bd

File tree

13 files changed

+615
-72
lines changed

13 files changed

+615
-72
lines changed

solution/0300-0399/0316.Remove Duplicate Letters/README.md

+113-2
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,40 @@
4040

4141
<!-- 这里可写通用的实现逻辑 -->
4242

43-
**方法一:单调栈**
43+
**方法一:栈**
44+
45+
我们用一个数组 `last` 记录每个字符最后一次出现的位置,用栈来保存结果字符串,用一个数组 `vis` 或者一个整型变量 `mask` 记录当前字符是否在栈中。
46+
47+
遍历字符串 $s$,对于每个字符 $c$,如果 $c$ 不在栈中,我们就需要判断栈顶元素是否大于 $c$,如果大于 $c$,且栈顶元素在后面还会出现,我们就将栈顶元素弹出,将 $c$ 压入栈中。
48+
49+
最后将栈中元素拼接成字符串作为结果返回。
50+
51+
时间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
4452

4553
<!-- tabs:start -->
4654

4755
### **Python3**
4856

4957
<!-- 这里可写当前语言的特殊实现逻辑 -->
5058

59+
```python
60+
class Solution:
61+
def removeDuplicateLetters(self, s: str) -> str:
62+
last = defaultdict(int)
63+
for i, c in enumerate(s):
64+
last[c] = i
65+
stk = []
66+
vis = set()
67+
for i, c in enumerate(s):
68+
if c in vis:
69+
continue
70+
while stk and stk[-1] > c and last[stk[-1]] > i:
71+
vis.remove(stk.pop())
72+
stk.append(c)
73+
vis.add(c)
74+
return ''.join(stk)
75+
```
76+
5177
```python
5278
class Solution:
5379
def removeDuplicateLetters(self, s: str) -> str:
@@ -70,10 +96,95 @@ class Solution:
7096
return ''.join(stack)
7197
```
7298

73-
### **Go**
99+
### **Java**
74100

75101
<!-- 这里可写当前语言的特殊实现逻辑 -->
76102

103+
```java
104+
class Solution {
105+
public String removeDuplicateLetters(String s) {
106+
int n = s.length();
107+
int[] last = new int[26];
108+
for (int i = 0; i < n; ++i) {
109+
last[s.charAt(i) - 'a'] = i;
110+
}
111+
Deque<Character> stk = new ArrayDeque<>();
112+
int mask = 0;
113+
for (int i = 0; i < n; ++i) {
114+
char c = s.charAt(i);
115+
if (((mask >> (c - 'a')) & 1) == 1) {
116+
continue;
117+
}
118+
while (!stk.isEmpty() && stk.peek() > c && last[stk.peek() - 'a'] > i) {
119+
mask ^= 1 << (stk.pop() - 'a');
120+
}
121+
stk.push(c);
122+
mask |= 1 << (c - 'a');
123+
}
124+
StringBuilder ans = new StringBuilder();
125+
for (char c : stk) {
126+
ans.append(c);
127+
}
128+
return ans.reverse().toString();
129+
}
130+
}
131+
```
132+
133+
### **C++**
134+
135+
```cpp
136+
class Solution {
137+
public:
138+
string removeDuplicateLetters(string s) {
139+
int n = s.size();
140+
int last[26] = {0};
141+
for (int i = 0; i < n; ++i) {
142+
last[s[i] - 'a'] = i;
143+
}
144+
string ans;
145+
int mask = 0;
146+
for (int i = 0; i < n; ++i) {
147+
char c = s[i];
148+
if ((mask >> (c - 'a')) & 1) {
149+
continue;
150+
}
151+
while (!ans.empty() && ans.back() > c && last[ans.back() - 'a'] > i) {
152+
mask ^= 1 << (ans.back() - 'a');
153+
ans.pop_back();
154+
}
155+
ans.push_back(c);
156+
mask |= 1 << (c - 'a');
157+
}
158+
return ans;
159+
}
160+
};
161+
```
162+
163+
### **Go**
164+
165+
```go
166+
func removeDuplicateLetters(s string) string {
167+
last := make([]int, 26)
168+
for i, c := range s {
169+
last[c-'a'] = i
170+
}
171+
stk := []rune{}
172+
vis := make([]bool, 128)
173+
for i, c := range s {
174+
if vis[c] {
175+
continue
176+
}
177+
for len(stk) > 0 && stk[len(stk)-1] > c && last[stk[len(stk)-1]-'a'] > i {
178+
vis[stk[len(stk)-1]] = false
179+
stk = stk[:len(stk)-1]
180+
}
181+
stk = append(stk, c)
182+
vis[c] = true
183+
}
184+
return string(stk)
185+
}
186+
```
187+
77188
```go
78189
func removeDuplicateLetters(s string) string {
79190
count, in_stack, stack := make([]int, 128), make([]bool, 128), make([]rune, 0)

solution/0300-0399/0316.Remove Duplicate Letters/README_EN.md

+104-1
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,30 @@
3434

3535
## Solutions
3636

37-
**Monotonic Stack**
37+
**Stack**
3838

3939
<!-- tabs:start -->
4040

4141
### **Python3**
4242

43+
```python
44+
class Solution:
45+
def removeDuplicateLetters(self, s: str) -> str:
46+
last = defaultdict(int)
47+
for i, c in enumerate(s):
48+
last[c] = i
49+
stk = []
50+
vis = set()
51+
for i, c in enumerate(s):
52+
if c in vis:
53+
continue
54+
while stk and stk[-1] > c and last[stk[-1]] > i:
55+
vis.remove(stk.pop())
56+
stk.append(c)
57+
vis.add(c)
58+
return ''.join(stk)
59+
```
60+
4361
```python
4462
class Solution:
4563
def removeDuplicateLetters(self, s: str) -> str:
@@ -62,8 +80,93 @@ class Solution:
6280
return ''.join(stack)
6381
```
6482

83+
### **Java**
84+
85+
```java
86+
class Solution {
87+
public String removeDuplicateLetters(String s) {
88+
int n = s.length();
89+
int[] last = new int[26];
90+
for (int i = 0; i < n; ++i) {
91+
last[s.charAt(i) - 'a'] = i;
92+
}
93+
Deque<Character> stk = new ArrayDeque<>();
94+
int mask = 0;
95+
for (int i = 0; i < n; ++i) {
96+
char c = s.charAt(i);
97+
if (((mask >> (c - 'a')) & 1) == 1) {
98+
continue;
99+
}
100+
while (!stk.isEmpty() && stk.peek() > c && last[stk.peek() - 'a'] > i) {
101+
mask ^= 1 << (stk.pop() - 'a');
102+
}
103+
stk.push(c);
104+
mask |= 1 << (c - 'a');
105+
}
106+
StringBuilder ans = new StringBuilder();
107+
for (char c : stk) {
108+
ans.append(c);
109+
}
110+
return ans.reverse().toString();
111+
}
112+
}
113+
```
114+
115+
### **C++**
116+
117+
```cpp
118+
class Solution {
119+
public:
120+
string removeDuplicateLetters(string s) {
121+
int n = s.size();
122+
int last[26] = {0};
123+
for (int i = 0; i < n; ++i) {
124+
last[s[i] - 'a'] = i;
125+
}
126+
string ans;
127+
int mask = 0;
128+
for (int i = 0; i < n; ++i) {
129+
char c = s[i];
130+
if ((mask >> (c - 'a')) & 1) {
131+
continue;
132+
}
133+
while (!ans.empty() && ans.back() > c && last[ans.back() - 'a'] > i) {
134+
mask ^= 1 << (ans.back() - 'a');
135+
ans.pop_back();
136+
}
137+
ans.push_back(c);
138+
mask |= 1 << (c - 'a');
139+
}
140+
return ans;
141+
}
142+
};
143+
```
144+
65145
### **Go**
66146
147+
```go
148+
func removeDuplicateLetters(s string) string {
149+
last := make([]int, 26)
150+
for i, c := range s {
151+
last[c-'a'] = i
152+
}
153+
stk := []rune{}
154+
vis := make([]bool, 128)
155+
for i, c := range s {
156+
if vis[c] {
157+
continue
158+
}
159+
for len(stk) > 0 && stk[len(stk)-1] > c && last[stk[len(stk)-1]-'a'] > i {
160+
vis[stk[len(stk)-1]] = false
161+
stk = stk[:len(stk)-1]
162+
}
163+
stk = append(stk, c)
164+
vis[c] = true
165+
}
166+
return string(stk)
167+
}
168+
```
169+
67170
```go
68171
func removeDuplicateLetters(s string) string {
69172
count, in_stack, stack := make([]int, 128), make([]bool, 128), make([]rune, 0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public:
3+
string removeDuplicateLetters(string s) {
4+
int n = s.size();
5+
int last[26] = {0};
6+
for (int i = 0; i < n; ++i) {
7+
last[s[i] - 'a'] = i;
8+
}
9+
string ans;
10+
int mask = 0;
11+
for (int i = 0; i < n; ++i) {
12+
char c = s[i];
13+
if ((mask >> (c - 'a')) & 1) {
14+
continue;
15+
}
16+
while (!ans.empty() && ans.back() > c && last[ans.back() - 'a'] > i) {
17+
mask ^= 1 << (ans.back() - 'a');
18+
ans.pop_back();
19+
}
20+
ans.push_back(c);
21+
mask |= 1 << (c - 'a');
22+
}
23+
return ans;
24+
}
25+
};
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
func removeDuplicateLetters(s string) string {
2-
count, in_stack, stack := make([]int, 128), make([]bool, 128), make([]rune, 0)
3-
for _, c := range s {
4-
count[c] += 1
2+
last := make([]int, 26)
3+
for i, c := range s {
4+
last[c-'a'] = i
55
}
6-
7-
for _, c := range s {
8-
count[c] -= 1
9-
if in_stack[c] {
6+
stk := []rune{}
7+
vis := make([]bool, 128)
8+
for i, c := range s {
9+
if vis[c] {
1010
continue
1111
}
12-
for len(stack) > 0 && stack[len(stack)-1] > c && count[stack[len(stack)-1]] > 0 {
13-
peek := stack[len(stack)-1]
14-
stack = stack[0 : len(stack)-1]
15-
in_stack[peek] = false
12+
for len(stk) > 0 && stk[len(stk)-1] > c && last[stk[len(stk)-1]-'a'] > i {
13+
vis[stk[len(stk)-1]] = false
14+
stk = stk[:len(stk)-1]
1615
}
17-
stack = append(stack, c)
18-
in_stack[c] = true
16+
stk = append(stk, c)
17+
vis[c] = true
1918
}
20-
return string(stack)
19+
return string(stk)
2120
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public String removeDuplicateLetters(String s) {
3+
int n = s.length();
4+
int[] last = new int[26];
5+
for (int i = 0; i < n; ++i) {
6+
last[s.charAt(i) - 'a'] = i;
7+
}
8+
Deque<Character> stk = new ArrayDeque<>();
9+
int mask = 0;
10+
for (int i = 0; i < n; ++i) {
11+
char c = s.charAt(i);
12+
if (((mask >> (c - 'a')) & 1) == 1) {
13+
continue;
14+
}
15+
while (!stk.isEmpty() && stk.peek() > c && last[stk.peek() - 'a'] > i) {
16+
mask ^= 1 << (stk.pop() - 'a');
17+
}
18+
stk.push(c);
19+
mask |= 1 << (c - 'a');
20+
}
21+
StringBuilder ans = new StringBuilder();
22+
for (char c : stk) {
23+
ans.append(c);
24+
}
25+
return ans.reverse().toString();
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
class Solution:
22
def removeDuplicateLetters(self, s: str) -> str:
3-
count, in_stack = [0] * 128, [False] * 128
4-
stack = []
5-
for c in s:
6-
count[ord(c)] += 1
7-
for c in s:
8-
count[ord(c)] -= 1
9-
if in_stack[ord(c)]:
3+
last = defaultdict(int)
4+
for i, c in enumerate(s):
5+
last[c] = i
6+
stk = []
7+
vis = set()
8+
for i, c in enumerate(s):
9+
if c in vis:
1010
continue
11-
while len(stack) and stack[-1] > c:
12-
peek = stack[-1]
13-
if count[ord(peek)] < 1:
14-
break
15-
in_stack[ord(peek)] = False
16-
stack.pop()
17-
stack.append(c)
18-
in_stack[ord(c)] = True
19-
return ''.join(stack)
11+
while stk and stk[-1] > c and last[stk[-1]] > i:
12+
vis.remove(stk.pop())
13+
stk.append(c)
14+
vis.add(c)
15+
return ''.join(stk)

0 commit comments

Comments
 (0)