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();
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM