LeetCode题目: Remove Duplicate Letters

问题描述

给一个字符串(只包含小写字母),删除重复的字母,

使得每个字母只出现一次。返回的结果必须是字典顺序最小的。

举例:“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;
    }
};

 

 
posted @ 2015-12-28 14:24  Runnyu  阅读(213)  评论(0编辑  收藏  举报