LeetCode——不同字符的最小子序列/去除重复字母
Q:返回字符串 text?中按字典序排列最小的子序列,该子序列包含?text?中所有不同字符一次。
示例 1:
输入:"cdadabcc"
输出:"adbc"
示例 2:
输入:"abcd"
输出:"abcd"
示例 3:
输入:"ecbacba"
输出:"eacb"
示例 4:
输入:"leetcode"
输出:"letcod"
A:贪心,遍历text,当前遍历到的字母c在字典序小于栈顶元素且后续还能找到当前栈顶元素时,就让栈顶弹出,然后把当前元素压进栈。
使用一个map记录每个值出现的最后位置,使用set记录栈中元素。
public static String smallestSubsequence(String text) { if (text.length() <= 1) return text; Map<Character, Integer> map = new HashMap<>(); for (int i = 0; i < text.length(); i++) { map.put(text.charAt(i), i);//记录每个元素出现的最后位置 } StringBuilder res = new StringBuilder(); Stack<Character> stack = new Stack<>(); Set<Character> set = new HashSet<>(); for (int i = 0; i < text.length(); i++) { char ch = text.charAt(i); if (set.contains(ch))//栈中已有,可以忽略 continue; if (stack.isEmpty() || stack.peek() < ch) { stack.add(ch); set.add(ch); } else { while (!stack.isEmpty() && stack.peek() > ch) { if (map.get(stack.peek()) > i) {//后面还会出现,可以弹出 set.remove(stack.pop()); } else break; } stack.add(ch); set.add(ch); } } while (stack.size() > 0) { res.insert(0, stack.pop()); } return res.toString(); }