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的一天哦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值