1. 程式人生 > >Leetcode 316. Remove Duplicate Letters

Leetcode 316. Remove Duplicate Letters

Problem:

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 1:

Input: "bcabc"
Output: "abc"

Example 2:

Input: "cbacdcbc"
Output: "acdb"

Solution:

  這道題提示我們用棧解決,但我仍然沒想出來如何使用棧,看了別人的解答後發現這道題的棧不是常規的遞增棧或遞減棧。這裡我們用了一個計數器count和visit陣列判斷是否使用過該字元。比如說”cbacdcbc“這個字串,我們來解釋下如何推出結果

1. cbacdcbc

    ^               

    result = "c"

2. cbacdcbc

      ^                //由於b比c小且b之後還有c,所以我們可以把c刪去用b代替。

    result = "b"

3. cbacdcbc

        ^               //由於a比b小且a之後還有b,所以把b刪去用a代替

    result = "a"

4. cbacdcbc

          ^               //第二步中刪去的c第一次在這裡出現,不過這個c未必是最終確定的位置,因為後面可能還有c

    result = "ac"

5. cbacdcbc

            ^               

    result = "acd"

6. cbacdcbc

              ^               

    result = "acd"

7. cbacdcbc

               ^          //這裡b比d要小但不能再刪d了,因為b之後沒有d可以添加了,所以直接在acd後面加b

    result = "acdb"

8. cbacdcbc

                 ^               

    result = "acdb"

  通過以上的流程,我們得到結果acdb,程式碼如下。

Code:

 

 1 class Solution {
 2 public:
 3     string removeDuplicateLetters(string s) {
 4         string result = "";
 5         vector<int> count(128,0);
 6         vector<bool> visited(128,false);
 7         for(int i = 0;i != s.size();++i)
 8             count[s[i]]++;
 9         for(int i = 0;i != s.size();++i){
10             count[s[i]]--;
11             if(visited[s[i]]) continue;
12             while(s[i] < result.back() && count[result.back()] != 0){
13                 visited[result.back()] = false;
14                 result.pop_back();
15             }
16             result += s[i];
17             visited[s[i]] = true;
18         }
19         return result;
20     }
21 };