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 由小写英文字母组成
解法
- 这道题和 Leetcode 402 类似 移除掉k位数字 使得剩下的最少
- 比如 adcd 我们一定会删去第一个出现的d deda 我们会删除第二个d
- 通过两个例子我们可以知道 一定删去的这个数 比右边大
- 这里与Leetcode 402不一样的是 402中可以随便删除 只要剩下的位数够 如果剩下的多了 截取前面几个就行
- 这里要保证每个字符都要出现在答案中 且只能出现一次
- 所以 这个字符已经存在在答案中 不能加入 如果这个字符后面不在出现 也不能弹出
代码
#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的一天哦!