Leetcode (316) Remove Duplicate Letters

来源:互联网 发布:oppo网络销售授权书 编辑:程序博客网 时间:2024/05/16 11:50
  • 题目:

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”

  • 题意:给定一个字符串,要求移除字符串中的重复字母,最后使得最后的字符串字典序最小,返回该字符串。
  • 思路:

    • 考虑实例字符串”cbacdcbc”得到“acdb”的方式。之所以,第一个字母是’a’,是因为’cb’在后面还有,将’a’放在最开头比’bc’放在最开头字典序要小。
    • 再考虑为什么’b’只能放到最后,原因就是’b’后面没有’d’,因此只能在前面取得’d’。
    • 于是,很容易得到一个贪心策略,如果当前字母想放到前面使得字典序变小的话,只需要保证它往前移的过程中间的所有字母在后面仍然有即可。
    • 而考虑”aybx”字典序小于”axyb”,因此往前移时应当一直往前,直到后面没有那个字母为止,才能保证能够往前移动到一个最佳的位置。
  • 代码

class Solution {public:    string removeDuplicateLetters(string s) {        int cnt[128]={0};        for (auto ch: s)        {            cnt[ch]++;        }        bool has[128]={false};        string ans(26, ' ');        int len=0;        for (auto ch: s)        {            cnt[ch]--;            if (has[ch]) continue;            int idx=len-1, pos=len;            // 找到最佳位置            while (idx>=0 && cnt[ans[idx]] > 0)            {                if (ans[idx] > ch)                {                    pos=idx;                }                idx--;            }            // 前移过程            while (len > pos)            {                has[ans[len-1]] = false;                len--;            }            len = pos+1;            ans[pos] = ch;            has[ch] = true;        }        return ans.substr(0, len);    }};
0 0