[leetcode] 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"

分析:通過觀察每個字母下標的規律,以"cbacdcbc"為例,

第一步,計算下標(countIndex):

a  => 2,  

b  => 1, 6

c  => 0, 3, 5, 7

d  => 4

第二步,尋找符合條件的字母(findLetter):

如果一個字母的第一個下標小於其后每個字母最后一個下標,則該字母符合條件。比如 a 中的 2 小於 b 的 6,c 的 7,d 的 4,則 a 中的2符合條件。

第三步,刪除前面的下標(removeIndex):

不防設第二步中符合條件的字母為X,則刪除X下標之前的所有下標,並刪除X。比如X為a,X下標為2,則刪除 b 中的 1,c 中的 0,並把 a 刪除。

重復第二步,第三步,直到集合為空。

以 "cbacdcbc" 為例:

b  => 6

c  => 3, 5, 7

d  => 4
b  => 6



d  => 4

上述變換解釋:雖然 6 < 7,但 6 卻 > 4, 故 b 不符合,而 c 中的 3 小於其后的 4,故 c 符合。 

b  => 6

故最后生成 a -> c -> d -> b,即 acdb.

代碼如下:

    public String removeDuplicateLetters(String s) {
        StringBuilder res = new StringBuilder();
        HashMap<Character, ArrayList<Integer>> hm = new HashMap<Character, ArrayList<Integer>>();
        ArrayList<Character> reference = new ArrayList<Character>();
        countIndex(s, hm, reference);
        Collections.sort(reference);
        while (!reference.isEmpty()) {
            int lettIndex = findLetter(s, res, hm, reference);
            removeIndex(lettIndex, hm, reference);
        }
        return res.toString();
    }
    
    private void countIndex(String s, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (! hm.containsKey(ch)) {
                ArrayList<Integer> tmp = new ArrayList<Integer>();
                tmp.add(i);
                hm.put(ch, tmp);
                reference.add(ch);
            } else {
                hm.get(ch).add(i);
            }
        }
    }
    
    private int findLetter(String s, StringBuilder res, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
        int m = 0;
        for (int i = 0; i < reference.size(); i++) {
            m = hm.get(reference.get(i)).get(0);
            int j = i+1;
            for (; j < reference.size(); j++) {
                ArrayList<Integer> tmp = hm.get(reference.get(j));
                if (m > tmp.get(tmp.size()-1)) {
                    break;
                }
            }
            if (j == reference.size()) {
                res.append(reference.get(i));
                reference.remove(i);
                break;
            }
        }
        return m;
    }
    
    private void removeIndex(int lett, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
        for (int i = 0; i < reference.size(); i++) {
            ArrayList<Integer> tmp = hm.get(reference.get(i));
            while (!tmp.isEmpty() && tmp.get(0) < lett) {
                tmp.remove(0);
            }
        }
    }

 


免責聲明!

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



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