Leetcode刷题笔记 316. 去除重复字母

  • 时间:
  • 来源:互联网
  • 文章标签:

316. 去除重复字母

时间:2020年12月23日
知识点:贪心、模拟
题目链接:https://leetcode-cn.com/problems/remove-duplicate-letters/

题目
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

注意:该题与 1081相同

示例 1
输入:s = “bcabc”
输出:“abc”

示例 2
输入:s = “cbacdcbc”
输出:“acdb”

提示

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

解法

  1. 这道题和 Leetcode 402 类似 移除掉k位数字 使得剩下的最少
  2. 比如 adcd 我们一定会删去第一个出现的d deda 我们会删除第二个d
  3. 通过两个例子我们可以知道 一定删去的这个数 比右边大
  4. 这里与Leetcode 402不一样的是 402中可以随便删除 只要剩下的位数够 如果剩下的多了 截取前面几个就行
  5. 这里要保证每个字符都要出现在答案中只能出现一次
  6. 所以 这个字符已经存在在答案中 不能加入 如果这个字符后面不在出现 也不能弹出

代码

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
class Solution {
public:
    string removeDuplicateLetters(string s) {
        vector<int> nums(26,0),vis(26,0);
        for(int i = 0;i < s.size(); i++)
            nums[s[i]-'a']++;
        string ans;
        for(char x : s){
            if(vis[x-'a'] == 0){//这个字符没有出现在答案中
                while(!ans.empty() && ans.back() > x){//如果 ans的末尾比这个字符大
                    if(nums[x-'a']>0){ //且后面存在这个字符 弹出 并更新
                        vis[ans.back() - 'a'] = 0;
                        ans.pop_back();
                    }else
                        break;
                }
                ans.push_back(x); //放入新的数组
                vis[x-'a'] = 1;
            }
            nums[x-'a']--;
        }
        return ans;
    }
};
int main()
{
    Solution S;
    string s = "cbacdcbc";
    cout<<S.removeDuplicateLetters(s)<<endl;
    return 0;
}

今天也是爱zz的一天哦!

本文链接http://www.taodudu.cc/news/show-1944722.html