316. Remove Duplicate Letters

题目链接:https://leetcode.com/problems...

用一个stack来做,stack里面的字母按增序来排,出现top>cur的时候要把top给pop出来,注意一点是如果后面没有top的话,就不能pop出来,所以先要用个hashmap来保存每个字母出现的次数,次数到0说明后面没有这个字母了,还需要一个visited数组来保存已经在stack里面的字母

  1. pop: while top > cur && map[top] > 0

  2. push: when !visited[cur]

loop invariant是(0, i)是到i为止最小的字母order结果。

public class Solution {
    public String removeDuplicateLetters(String s) {
        // count the number of each character
        int[] map = new int[26];
        for(char c : s.toCharArray()) {
            map[c - 'a']++;
        }
        // stack to store the smallest lexi order
        char[] stack = new char[s.length()];
        // visited to record already added letter
        boolean[] visited = new boolean[26];
        int i = 0;
        for(char c : s.toCharArray()) {
            map[c - 'a']--;
            if(visited[c - 'a']) continue;
            // pop top character if it is > c && there are remains in the right
            while(i > 0 && stack[i-1] > c && map[stack[i-1] - 'a'] > 0) {
                visited[stack[i-1] - 'a'] = false;
                i--;
            }
            stack[i++] = c;
            visited[c-'a'] = true;
        }
        
        return new String(stack, 0, i);
    }
}

以及枚举的做法,因为这题只有26个字母,枚举的复杂度是O(26*N),参考博客:
http://bookshadow.com/weblog/...

还有先把string排序,然后从小到大取字母的写法,参考discussion:
https://discuss.leetcode.com/...


lulouch13
13 声望6 粉丝