LeetCode 316. Remove Duplicate Letters

最后输出结果中字母的顺序应该保留输入字符串中的顺序,而且字典序最小,比如输入"cbacdcbc",输出"acdb",这四个字母的先后顺序遵循输入中的顺序,同时字典序最小。

 

下面这份代码的大致思路是首先把s中每个字母出现次数统计一次,然后再遍历一次,minLetterIndex保存目前为止出现的字母中字典序最小字母的位置,同时每遇到一个字母,对应的出现次数减一,当减完后次数归0时,就break,也即该字母只在目前这段字符串中出现。break后将s[minLetterIndex]加入结果字符串ret中,s取minLetterIndex + 1(包括)到结尾的一段,同时擦去minLetterIndex对应的字母。在s的长度不为0时一直执行这个操作。

removeLetter函数的思路是保持着s的更新,使[0,k-1]不包括ch,比如输入分别为"aed","e",那么for循环过后s="add",所以擦去k开始(包含k)到结尾的一段。

 

看懂代码但没明白为什么这么做可以保证输出符合要求,留坑。另外不知道为什么tag是stack,先跟风打一个。

 1 class Solution {
 2 public:
 3     string removeDuplicateLetters(string s) {
 4         string ret;
 5         vector<int> letterCount;
 6         int len = s.length();
 7         int i = 0, minLetterIndex = 0;
 8         char ch;
 9 
10         while (len)
11         {
12             minLetterIndex = 0;
13             letterCount.assign(26, 0);
14 
15             for (i = 0; i < len; ++i)
16                 ++letterCount[ s[i]-'a' ];
17 
18             for (i = 0; i < len; ++i)
19             {
20                 if (s[i] < s[minLetterIndex])
21                     minLetterIndex = i;
22 
23                 --letterCount[ s[i]-'a' ];
24                 if (letterCount[ s[i]-'a' ] == 0)
25                     break;
26             }  
27 
28             ret += s[minLetterIndex];
29             ch = s[minLetterIndex];
30             s = s.substr(minLetterIndex + 1);
31             removeLetter(s, ch);
32             len = s.length();
33         }
34 
35         return ret;
36     }
37     void removeLetter(string &s, char ch)
38     {
39         int len = s.length(), i = 0;
40         int k = 0;
41 
42         for (i = 0; i < len; ++i)
43         {
44             if (s[i] != ch)
45                 s[k++] = s[i];
46         }
47 
48         s.erase(k, len-k);
49     }
50 };

 

posted @ 2016-04-04 19:45  co0oder  阅读(1321)  评论(0编辑  收藏  举报