LeetCode(316)Remove Duplicate Letters

来源:互联网 发布:vb自定义数据类型 编辑:程序博客网 时间:2024/04/30 01:47

题目:

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"

给定一个只包含小写字母、含有重复字母的字符串,要求去掉里面的重复字母,使得每个字母只出现一次。在所有可能结果中选择字典序最小的结果。

分析:有很多种去重结果,难点在于如何得到最小的字符串。使用贪心方法:由于字母不重复,所以结果中最多只有26个字母。我们可以逐个添加这些字母,在可以满足的情况下,优先添加ASCII码值小的字母,这样得到的结果一定是字典序最小的。

那么什么情况是可以满足的呢?

结果序列中的字母相对顺序要和原序列相同。假如结果序列中有子序列cd,那么在原序列中,c后面一定要有d,否则就产生冲突。所以选择的时候,尽可能选择原序列中最左边的c,然后选择c之后,在原序列被选择的c后面的字符串中,选择最先出现的d。

为了找到可满足的ASCII码最小的字母,可以遍历原序列。最前面的字母一定满足。从前往后遍历,如果某个字母后面的序列仍然包含所有未添加的字母,那么它是满足的。否则,它是不满足的,它后面的字母也不满足。我们可以通过对字符计数来检查某个字母后面的序列是否包含了所有未添加的字母。

代码:

class Solution {public:    string removeDuplicateLetters(string s) {        bool notAdd[26];//在原序列中出现,但还没有加入到结果序列的字母        int rest=0;//还没有添加进结果序列的字母个数        string resStr;//结果        for(int i=0;i<26;i++) notAdd[i]=false;        for(int i=0;i<s.length();i++)            if(!notAdd[s[i]-'a'])            {                rest++;                notAdd[s[i]-'a']=true;            }                    int pos=-1;//最后一个已添加字母的下标,新添加的字母下标必须大于pos才能保证顺序不乱        while(rest>0)//每次添加一个满足要求并且最小的字母        {            int cnt[26]={0};//统计每个(未添加)的字母的出现次数            for(int i=pos+1;i<s.length();i++)                if(notAdd[s[i]-'a'])                    cnt[s[i]-'a']++;                                            int minChar='z'+1;//可以添加的最小字母            int minIndex;//可以添加的最小的字母的下标                        for(int i=pos+1;i<s.length();i++)//找最小            {                if(notAdd[s[i]-'a'])//忽略已添加的字母                {                    if(minChar>s[i]){ minChar=s[i];minIndex=i;}                    cnt[s[i]-'a']--;                    if(cnt[s[i]-'a']==0) break;//如果后面的字符串中缺少了某个未添加的字母,就不满足要求了。                }            }                        resStr+=minChar;            notAdd[minChar-'a']=false;            rest--;            pos=minIndex;        }        return resStr;    }};

复杂度:O(26*n),n是字符串长度。

0 0
原创粉丝点击