问题描述
给一个字符串(只包含小写字母),删除重复的字母,
使得每个字母只出现一次。返回的结果必须是字典顺序最小的。
举例:“bcabc" -> "abc", "cbacdcbc" -> "acdb"。
提示:stack、greed
解决本题的关键是如何使用贪心策略
下面C++的实现使用的是这样的策略:
令目标字符串为空,每增加一位就遍历a-z,根据条件来判断当前字符是否可以添加到目标字符串。
因为遍历顺序是字典顺序,因此只要符合条件即可判定该字符就是需要添加的字符。
贪心算法的思想就是选择局部最优的,以达到全局最优。而这样的策略符合贪心选择性质。
#include <iostream> #include <string> #include <algorithm> using namespace std; class Solution { public: string removeDuplicateLetters(string s) { if(s.empty()) return ""; int pos1 = 0,pos2,i; char ch; bool flag; string s1; //结束条件 while(pos1 < s.length()) { //遍历26个字母 for(ch = 'a';ch <= 'z';++ch) { flag = true; //判断当前字符是否已经存在于S1 if(s1.find(ch) != s1.npos) { if(ch == 'z') pos1 ++; continue; } //判断当前字符是否在S->pos1之后 if((pos2 = s.find(ch,pos1)) == s.npos) { //如果最后一个都没找到 if(ch == 'z') pos1 ++; continue; } //判断当前字符是否符合条件 for(i = pos1;i < pos2;++i) { //只要[pos1,pos2)中存在一个不符合的就退出 if(s.find(s[i],i + 1) == s.npos && s1.find(s[i]) == s1.npos) { flag = false; break; } } if(flag) { s1.push_back(ch); pos1 = pos2 + 1; break; } } } return s1; } };