
题目要求
- 去除字符串中的重复字母;
- 不打乱相对位置;
- 输出字典序最小。
方法
- 遍历字符串元素并维护一个栈
- 当准备入栈的元素比栈顶大的时候顺利压入
- 当准备压入栈的元素比栈顶小的时候将栈顶元素弹出直至满足比栈顶元素大
- 当准备弹出栈的元素在后续的字符串遍历中无法再出现(该元素的最后一个幸存者)则拒绝弹出,元素压入,遍历继续
- 对被压入的元素做记录,在后续遍历中若该元素已经压入过了,则跳过
class Solution {
public String removeDuplicateLetters(String s) {
char[] arr = s.toCharArray();
Stack<Character> stack = new Stack<>();
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
map.put(arr[i], i);
}
Set<Character> set = new HashSet<>();
for (int i = 0; i < arr.length; i++) {
if (set.contains(arr[i])) {
continue;
}
if (!stack.isEmpty() && arr[i] < stack.peek()) {
while (!stack.isEmpty()
&& arr[i] < stack.peek() && map.get(stack.peek()) > i) {
set.remove(stack.pop());
}
}
stack.push(arr[i]);
set.add(arr[i]);
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
return sb.reverse().toString();
}
}