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

Example:

Given "bcabc"
Return "abc"

Given "cbacdcbc"
Return "acdb"

思路

这道题目的最优解还不是那么容易想到,解释起来还比较费劲。我下面结合具体例子来说明一下吧。

首先我们统计每个字符出现的次数,这样在顺序扫描字符串的时候,就可以知道后面还会不会再出现这个字符。在顺序扫描的时候,如果发现当前字符比结果中的最后一个字符小,并且结果中的最后一个字符在后面还会出现,那么就把结果中的最后一个字符弹出,这是因为弹出后形成的字符串的字典序必然比不弹出的小。以字符串bcabc为例:

1)b:由于此时结果集为空,所以加入结果集,使得ret == “b”;

2)c:由于c > ret.back() == b,所以c直接加入结果集,此时ret == “bc”;

3)a:由于a < c,并且c在之后还会出现,所以不用此时的c,把c从结果集中弹出,此时ret == “b”;此时仍然有a < b,并且b在之后还会出现,所以不用此时的b,把b从结果集中弹出,此时ret == ""。最后再加入a,使得ret == “a”;

4)b:此时b > a,所以在结果集中加入b,使得 ret == "ab";

5)c:此时c > b,所以在结果集中加入c,使得 ret == “abc”。这就是最终结果。

算法的空间复杂度是输出敏感性的,最高可以达到O(n),时间复杂度是O(n),因为每个字符最多被入栈和出栈各一次。

代码

class Solution {
public:
    string removeDuplicateLetters(string s) {
        string ret;
        vector<int> hash(26, 0);
        vector<bool> visited(26, false);
        for(auto ch : s) {
            ++hash[ch - 'a'];
        }
        for(auto ch : s) {
            --hash[ch - 'a'];
            if(visited[ch - 'a']) {
                continue;
            }
            while(ret.size() > 0 && ch < ret.back() && hash[ret.back() - 'a'] > 0) {
                visited[ret.back() - 'a'] = false;
                ret.pop_back();
            }
            ret += ch;
            visited[ch - 'a'] = true;
        }
        return ret;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值