LeetCode-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.

题目大意

字符串中只包含‘a’-‘z‘,且其中包含重复的字母,要求去掉重复的字母,使其字符串中的字母均唯一,同时得到的所有可能的结果具有最小字典序。

示例

E1

Input: "bcabc"
Output: "abc"

E2

Input: "cbacdcbc"
Output: "acdb"

解题思路

用数组先保存所有字母出现的次数,再遍历一边字符串,若出现当前的字母只出现了一次,则直接加入结果中,否则需要判断其与结果中的最后一个字母比谁更大,如果新插入的字母更小,则需要将结果末尾的字母删除,将新字母加入,遍历到字符串最后得到最终结果。

复杂度分析

时间复杂度:O(N)

空间复杂度:O(N)

代码

class Solution {
public:
    string removeDuplicateLetters(string s) {
        // 保存字母出现的次数
        vector<int> character(26, 0);
        // 保存该字母之前是否访问过
        vector<bool> vis(26, false);
        // 最终结果最前应加入一个小于’a‘的字母
        string res = "0";
        // 记录字符串中各个字母出现的次数
        for(char c : s)
            character[c - 'a']++;
        
        for(int i = 0; i < s.length(); ++i) {
            character[s[i] - 'a']--;
            // 如果之前出现过,则跳过
            if(vis[s[i] - 'a'])
                continue;
            // 否则,进行判断是否其大小小于结果最后一位字母,或其数量是否为最后一个
            while(s[i] < res.back() && character[res.back() - 'a']) {
                vis[res.back() - 'a'] = false;
                res.pop_back();
            }
            // 将该字母加入最终结果
            vis[s[i] - 'a'] = true;
            res += s[i];
        }

        return res.substr(1);
    }
};
原文地址:https://www.cnblogs.com/heyn1/p/11176081.html