-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathRemoveDuplicateLetters316.java
89 lines (77 loc) · 2.71 KB
/
RemoveDuplicateLetters316.java
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* Given a string which contains only lowercase letters, remove duplicate letters so that every
* letter appear once and only once. You must make sure your result is the smallest in
* lexicographical order among all possible results.
*
* Example:
* Given "bcabc"
* Return "abc"
*
* Given "cbacdcbc"
* Return "acdb"
*/
public class RemoveDuplicateLetters316 {
/**
* https://leetcode.com/problems/remove-duplicate-letters/discuss/76766/Easy-to-understand-iterative-Java-solution
*/
public String removeDuplicateLetters(String s) {
if (s == null || s.length() <= 1) return s;
Map<Character, Integer> lastPosMap = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
lastPosMap.put(s.charAt(i), i);
}
char[] result = new char[lastPosMap.size()];
int begin = 0, end = findMinLastPos(lastPosMap);
for (int i = 0; i < result.length; i++) {
char minChar = 'z' + 1;
for (int k = begin; k <= end; k++) {
if (lastPosMap.containsKey(s.charAt(k)) && s.charAt(k) < minChar) {
minChar = s.charAt(k);
begin = k+1;
}
}
result[i] = minChar;
if (i == result.length-1) break;
lastPosMap.remove(minChar);
if (s.charAt(end) == minChar) end = findMinLastPos(lastPosMap);
}
return new String(result);
}
private int findMinLastPos(Map<Character, Integer> lastPosMap) {
if (lastPosMap == null || lastPosMap.isEmpty()) return -1;
int minLastPos = Integer.MAX_VALUE;
for (int lastPos : lastPosMap.values()) {
minLastPos = Math.min(minLastPos, lastPos);
}
return minLastPos;
}
/**
* https://leetcode.com/problems/remove-duplicate-letters/discuss/76762/Java-O(n)-solution-using-stack-with-detail-explanation
*/
public String removeDuplicateLetters2(String s) {
Stack<Character> stack = new Stack<>();
int[] count = new int[26];
char[] arr = s.toCharArray();
for(char c : arr) {
count[c-'a']++;
}
boolean[] visited = new boolean[26];
for(char c : arr) {
count[c-'a']--;
if(visited[c-'a']) {
continue;
}
while(!stack.isEmpty() && stack.peek() > c && count[stack.peek()-'a'] > 0) {
visited[stack.peek()-'a'] = false;
stack.pop();
}
stack.push(c);
visited[c-'a'] = true;
}
StringBuilder sb = new StringBuilder();
for(char c : stack) {
sb.append(c);
}
return sb.toString();
}
}