[ LeetCode ] #316. Remove Duplicate Letters(移除重复出现的字符)

题目:316. Remove Duplicate Letters

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"

题意:

给定一个仅包含小写字母的字符串,移除重复出现的字符,使得每个字符仅出现一次,并且保证得到的结果字母序为最小。

分析:

第一种简单暴力的思路,可以将所有的组合情况求出来 然后排序输出字典序最小的那个,但这种解法时间复杂度必然不符合题目要求。

第二种方法,可以借助stack的思想,首先统计出每个字符出现的次数,然后遍历 每次都将当前位置的字符放置到当前最优的位置,遍历过程中会出现以下几种情况:

  1. 当前遍历字符已经访问过,由上面分析可知,每遍历到一个字符都会将其放置到最优位置,因此当前遍历到的字符可以不做任何处理。
  2. 判断 如果当前用以保存最终结果的字符串ans为空,则说明当前字符为第一个字符,因此 也不需要对其寻找最优位置。那么如果不为空的情况下,则说明当前ans已经包含若干个字符,那么如何使得最终得到的字符串字典序最小呢?即 可以对ans从后往前查找 判断ans.back() 是否大于当前遍历到的字符 并且保证 ans.back()再后续遍历中还会出现,此时就做ans.pop_back()操作,同时将其访问状态置为false,以此找到当前字符的最优位置。
  3. 根据step2,说明已经找到当前情况下 当前字符的最优位置,将当前遍历字符压入结果ans尾部,并标记已访问。
  4. return ans;

Code

class Solution {
public:
    string removeDuplicateLetters(string s) {
       	vector cand(27,0);
        vector visit(27,0);
        for(char c:s)cand[c-'a']++;
        string ans="";
        for(char c:s){
            --cand[c-'a'];
            if(visit[c-'a'])continue;
            while(!ans.empty() && c

 

 

你可能感兴趣的:(leetcode)