File tree Expand file tree Collapse file tree 3 files changed +92
-0
lines changed Expand file tree Collapse file tree 3 files changed +92
-0
lines changed Original file line number Diff line number Diff line change 66
66
303. 区域和检索 - 数组不可变
67
67
304. 二维区域和检索 - 矩阵不可变
68
68
309. 最佳买卖股票时机含冷冻期
69
+ 316. 去除重复字母
69
70
322. 零钱兑换
70
71
338. 比特位计数
71
72
392. 判断子序列
99
100
739. 每日温度
100
101
1020. 飞地的数量
101
102
1035. 不相交的线
103
+ 1081. 不同字符的最小子序列
102
104
1143. 最长公共子序列
103
105
1254. 统计封闭岛屿的数目
104
106
1905. 统计子岛屿
Original file line number Diff line number Diff line change
1
+ // 316. 去除重复字母
2
+
3
+
4
+ /*
5
+ 单调递增栈
6
+ 实现思路:
7
+ 1、利用单调递增栈,如果当前字符小于栈顶字符,则栈顶字符出栈,最后当前字符入栈,保证了栈内单调递增,删除了高位上较大的字符,使字典序更小
8
+ 2、用inStack数组记录字符是否在栈中,存在则跳过,保证字母不重复
9
+ 3、用count数组记录字符的个数,弹出时校验剩余个数,保证字母用一次,使字典序更小
10
+
11
+ 算法过程:
12
+ 1、遍历字符数组
13
+ 1)每遍历一个字符,该字符的剩余个数就减1
14
+ 2)如果字符已经在栈中,那么不能重复添加,需跳过
15
+ 3)栈不为空 且 当前字符小于栈顶字符 且 栈顶字符剩余个数大于0,那么弹出栈顶字符且记录不在栈中。
16
+ 判断 栈顶字符剩余个数大于0 是因为当前在高位弹出该字符能使字典序更小,但要满足每个字符出现一次,所以有剩余后面再加入,当前才可以弹出
17
+ 4)将当前字符入栈,并记录在栈中
18
+ 2、栈不为空时,从栈底弹出字符拼凑字符串,返回字符串
19
+ */
20
+ class Solution {
21
+ public String removeDuplicateLetters (String s ) {
22
+ int [] count = new int [256 ];
23
+ boolean [] inStack = new boolean [256 ];
24
+ Deque <Character > stack = new ArrayDeque <>();
25
+ for (char c : s .toCharArray ()) {
26
+ count [c ]++;
27
+ }
28
+ for (char c : s .toCharArray ()) {
29
+ count [c ]--;
30
+ if (inStack [c ]) {
31
+ continue ;
32
+ }
33
+ while (!stack .isEmpty () && c < stack .peek () && count [stack .peek ()] > 0 ) {
34
+ inStack [stack .pop ()] = false ;
35
+ }
36
+ stack .push (c );
37
+ inStack [c ] = true ;
38
+ }
39
+ StringBuilder res = new StringBuilder ();
40
+ while (!stack .isEmpty ()) {
41
+ res .append (stack .pollLast ());
42
+ }
43
+ return res .toString ();
44
+ }
45
+ }
Original file line number Diff line number Diff line change
1
+ // 1081. 不同字符的最小子序列
2
+
3
+
4
+ /*
5
+ 单调递增栈
6
+ 实现思路:
7
+ 1、利用单调递增栈,如果当前字符小于栈顶字符,则栈顶字符出栈,最后当前字符入栈,保证了栈内单调递增,删除了高位上较大的字符,使字典序更小
8
+ 2、用inStack数组记录字符是否在栈中,存在则跳过,保证字母不重复
9
+ 3、用count数组记录字符的个数,弹出时校验剩余个数,保证字母用一次,使字典序更小
10
+
11
+ 算法过程:
12
+ 1、遍历字符数组
13
+ 1)每遍历一个字符,该字符的剩余个数就减1
14
+ 2)如果字符已经在栈中,那么不能重复添加,需跳过
15
+ 3)栈不为空 且 当前字符小于栈顶字符 且 栈顶字符剩余个数大于0,那么弹出栈顶字符且记录不在栈中。
16
+ 判断 栈顶字符剩余个数大于0 是因为当前在高位弹出该字符能使字典序更小,但要满足每个字符出现一次,所以有剩余后面再加入,当前才可以弹出
17
+ 4)将当前字符入栈,并记录在栈中
18
+ 2、栈不为空时,从栈底弹出字符拼凑字符串,返回字符串
19
+ */
20
+ class Solution {
21
+ public String smallestSubsequence (String s ) {
22
+ int [] count = new int [256 ];
23
+ boolean [] inStack = new boolean [256 ];
24
+ Deque <Character > stack = new ArrayDeque <>();
25
+ for (char c : s .toCharArray ()) {
26
+ count [c ]++;
27
+ }
28
+ for (char c : s .toCharArray ()) {
29
+ count [c ]--;
30
+ if (inStack [c ]) {
31
+ continue ;
32
+ }
33
+ while (!stack .isEmpty () && c < stack .peek () && count [stack .peek ()] > 0 ) {
34
+ inStack [stack .pop ()] = false ;
35
+ }
36
+ stack .push (c );
37
+ inStack [c ] = true ;
38
+ }
39
+ StringBuilder res = new StringBuilder ();
40
+ while (!stack .isEmpty ()) {
41
+ res .append (stack .pollLast ());
42
+ }
43
+ return res .toString ();
44
+ }
45
+ }
You can’t perform that action at this time.
0 commit comments