2017013

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:

Given

"bcabc"

Return
"abc"


Given
"cbacdcbc"

Return
"acdb"


Credits:
Special thanks to  @dietpepsi  for adding this problem and creating all test cases.



这道题让我们移除重复字母,使得每个字符只能出现一次,而且结果要按字母顺序排,前提是不能打乱其原本的相对位置。我们的解题思路是:先建立一个哈希表来统计每个字母出现的次数,还需要一个visited数字来纪录每个字母是否被访问过,我们遍历整个字符串,对于遍历到的字符,先在哈希表中将其值减一,然后看visited中是否被访问过,若访问过则继续循环,说明该字母已经出现在结果中并且位置已经安排妥当。如果没访问过,我们和结果中最后一个字母比较,如果该字母的ASCII码小并且结果中的最后一个字母在哈希表中的值不为0(说明后面还会出现这个字母),那么我们此时就要在结果中删去最后一个字母且将其标记为未访问,然后加上当前遍历到的字母,并且将其标记为已访问,以此类推直至遍历完整个字符串s,此时结果里的字符串即为所求。这里有个小技巧,我们一开始给结果字符串res中放个"0",就是为了在第一次比较时方便,如果为空就没法和res中的最后一个字符比较了,而‘0’的ASCII码要小于任意一个字母的,所以不会有问题。最后我们返回结果时再去掉开头那个‘0’即可,参见代码如下:



class Solution {
public:
    string removeDuplicateLetters(string s) {
        int m[256] = {0}, visited[256] = {0};
        string res = "0";
        for (auto a : s) ++m[a];
        for (auto a : s) {
            --m[a];
            if (visited[a]) continue;
            while (a < res.back() && m[res.back()]) {
                visited[res.back()] = 0;
                res.pop_back();
            }
            res += a;
            visited[a] = 1;
        }
        return res.substr(1);
    }
};






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值