316. 去除重复字母 (JAVA)

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

 

示例 1:

输入:s = "bcabc"
输出:"abc"
示例 2:

输入:s = "cbacdcbc"
输出:"acdb"
 

提示:

1 <= s.length <= 10^4

解题思路:

当前字母比前一个字母小,且,前一个字母有重复,那么前一个字母被舍弃
舍弃之后,判断再前一个字母是否也比当前字母小 -> 这里想到用栈,后进先判断。
class Solution {
    public String removeDuplicateLetters(String s) {
        int[] letterCnt = new int[26];
        for (int i = 0; i < s.length(); i++) {
            letterCnt[s.charAt(i) - 'a']++;
        }

        Stack<Character> letterStack = new Stack<>();
        Set<Character> curSet = new HashSet<>();
        for (int i = 0; i < s.length(); ) {
            if (curSet.contains(s.charAt(i))) { //如果之前出现过,则直接舍弃
                letterCnt[s.charAt(i)-'a']--;
                i++;
            } else if (!letterStack.isEmpty() && letterStack.peek() > s.charAt(i) && letterCnt[letterStack.peek()-'a'] > 1) { //如果比前一个字符小且前一个字符在之后会有重复出现,那么舍弃前一个字符
                curSet.remove(letterStack.peek());
                letterCnt[letterStack.pop()-'a']--;
            } else { //否则,入栈
                letterStack.push(s.charAt(i));
                curSet.add(s.charAt(i));
                i++;
            }
        }

        StringBuilder sb = new StringBuilder();
        while(!letterStack.isEmpty()) {
            sb.append(letterStack.pop());
        }
        return sb.reverse().toString();
    }
}

 

posted on 2023-07-22 16:45  joannae  阅读(42)  评论(0编辑  收藏  举报

导航