Remove Duplicate Letters

Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.

Example:

Given "bcabc"
Return "abc"

Given "cbacdcbc"
Return "acdb"

Credits:
Special thanks to  @dietpepsi for adding this problem and creating all test cases.

思路:单调递增栈保证了lexicographical order是最小的;为了保证字母顺序是最小的。那么也就是说,如果先遇见的字母,后面还有,而且比我当前的要靠后,那么pop之前的,先放我现在的。比如说bab, 先遇见b了,再遇见a,那么我看b后面还有,那么对不起,pop b,我后面再加上你。用stack来保存信息,并保存stack的信息永远是递增的,首先count一下字母的频率,遇见一个char,就把频率降低-1,如果当前遇见的char,已经被visit过了,那么直接跳过,如果没有,那么check count里面还有没有,没有就不pop,有的话,那么就pop,因为后面还有不要着急。然后最后再把stack里面的char组合起来,反向输送。

class Solution {
    public String removeDuplicateLetters(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        Stack<Character> stack = new Stack<>();
        int count[] = new int[26];
        boolean[] visited = new boolean[26];
        
        for(int i = 0; i < s.length(); i++) {
            count[s.charAt(i) - 'a']++;
        }
        
        // bab, 遇见a, pop第一个b,因为后面还有;
        for(int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            count[c - 'a']--;
            if(visited[c - 'a']) {
                continue;
            }
            // 如果当前的比c要大,而且后面还有,那么pop当前的;visited记住标记为false;
            while(!stack.isEmpty() && stack.peek() > c && count[stack.peek() - 'a'] > 0) {
                visited[stack.peek() - 'a'] = false;
                stack.pop();
            }
            visited[c - 'a'] = true;
            stack.push(c);
        }
        
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()) {
            sb.insert(0, stack.pop());
        }
        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值