316. 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"

一刷
題解:
讓我們移除重復(fù)字母,使得每個字符只能出現(xiàn)一次,而且結(jié)果要按字母順序排,前提是不能打亂其原本的相對位置。

public class Solution {
    public String removeDuplicateLetters(String s) {
        if(s == null || s.length() == 0) return s;
        int[] count = new int[26];
        char[] res = new char[26];
        int len = s.length();
        for(int i=0; i<len; i++){
            count[s.charAt(i) - 'a']++;
        }
        int pos = 0;
        for(int i=0; i<len; i++){
            if(s.charAt(i) < s.charAt(pos)) 
                pos = i;
            count[s.charAt(i) - 'a']--;
            if(count[s.charAt(i) - 'a'] == 0)
                break; // found first minimum char
        }
        
        String charToRemove = String.valueOf(s.charAt(pos));
        return charToRemove + removeDuplicateLetters(s.substring(pos+1).replaceAll(charToRemove, ""));
    }
}

二刷
用26維數(shù)組存儲詞頻,用26維boolean數(shù)組表示該character是否存在當(dāng)前的stack中。對于一個ch, 如果棧頂?shù)脑囟急萩h大,且棧頂元素的詞頻此時不為0(有dup),則一直pop. 最后用linkedlist模擬stack, 進(jìn)一步提高速度,stack中的順序即為remove dup后的字符串(從早到晚)

public class Solution {

   public static String removeDuplicateLetters(String sr) {
        int[] res = new int[26]; //will contain number of occurences of character (i+'a')
        boolean[] visited = new boolean[26]; //will contain if character (i+'a') is present in current result Stack
        char[] ch = sr.toCharArray();
        for(char c: ch){  //count number of occurences of character 
            res[c-'a']++;
        }
        Deque<Character> st = new LinkedList<>(); // answer stack
        int index;
        for(char s:ch){ 
            index= s-'a';
            res[index]--;   //decrement number of characters remaining in the string to be analysed
            if(visited[index]) //if character is already present in stack, dont bother
                continue;
            //if current character is smaller than last character in stack which occurs later in the string again
            //it can be removed and  added later e.g stack = bc remaining string abc then a can pop b and then c
            
            while(!st.isEmpty() && s<st.peekLast() && res[st.peekLast()-'a']!=0){ 
                visited[st.removeLast()-'a']=false;
            }
            st.addLast(s); //add current character and mark it as visited
            visited[index]=true;
        }

        StringBuilder sb = new StringBuilder();
        //pop character from stack and build answer string from back
        while(!st.isEmpty()){
            sb.append(st.pop());//from first to last
        }
        return sb.toString();
   }
}

三刷

class Solution {
    public String removeDuplicateLetters(String s) {
        int[] freq = new int[26];
        char[] strs = s.toCharArray();
        for(char ch : strs){
            freq[ch - 'a']++;
        }
        
        boolean[] visited = new boolean[26];
        LinkedList<Character> stack = new LinkedList<>();
        for(char ch : strs){
            int index = ch - 'a';
            freq[index]--;
            if(visited[index]) continue;//is in the stack
            while(!stack.isEmpty() && ch<stack.peekLast() && freq[stack.peekLast() - 'a']!=0){
                visited[stack.pollLast() - 'a'] = false;
            }
            stack.addLast(ch);
            visited[index] = true;
        }
        
        StringBuilder res = new StringBuilder();
        while(!stack.isEmpty()){
            res.append(stack.pollFirst());
        }
        return res.toString();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容