https://leetcode-cn.com/problems/remove-duplicate-letters/
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
思路: 1.标记字符是否已经使用过
2.标记字符后续是否还会出现
3.贪心法: 后来的字符如果比前面的小,如果前面的元素满足下面的条件,则弹出前面的元素,保证在前面的字符每次都选最小的字符
条件: 1)该字符后续还会出现
2)该字符比待插入的字符字典序大
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String input = in.nextLine();
int[] count = new int[128];
boolean[] useed = new boolean[128];
for (int i = 0; i < input.length(); i++) {
count[input.charAt(i)] += 1;
}
Stack<Character> stringStack = new Stack<>();
for (int i = 0; i < input.length(); i++) {
char s = input.charAt(i);
count[s]--;
// 已经使用过, 直接跳过
if (useed[s]) {
continue;
}
// 栈为空, 直接入栈
if (stringStack.isEmpty()) {
stringStack.push(s);
useed[s] = true;
} else {
while (!stringStack.empty() && stringStack.peek() > s) {
char peekChar = stringStack.peek();
// 当前字符和栈顶元素比较, 如果栈顶元素大于当前字符 且后续还能出现, 则栈顶元素出栈
if (count[peekChar] == 0) {
break;
}
stringStack.pop();
useed[peekChar] = false;
}
stringStack.push(s);
useed[s] = true;
}
}
StringBuilder stringBuilder = new StringBuilder();
while (!stringStack.empty()) {
stringBuilder.append(stringStack.pop());
}
;
System.out.println(stringBuilder.reverse());
}
}