贪心+栈
题意:
给我们一个字符串 S S S,让我们从中找到一个子序列满足以下两个条件:
- 包含字符串中所有出现过的字符各1个。
- 是所有满足条件1的串中,字典序最小的。
题解:
这题可以使用栈解决。对于当前字符串S的字符,让其与栈顶元素比较,如果当前字符小于栈顶元素,且该栈顶元素在之后的位置中还会出现,则出栈,直到不满足循环条件为止。最后当前字符入栈。
实现细节见代码:
#include <bits/stdc++.h>
using namespace std;
map<char, int> num, vis;
stack<char> ans;
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
string s;
cin >> s;
for (int i = 0; s[i]; i++) {
num[s[i]]++; // 记录每个元素出现次数
}
ans.push(s[0]);
num[s[0]]--;
vis[s[0]] = 1; // 表示当前字符已经在栈中
for (int i = 1; s[i]; i++) {
while (!vis[s[i]] && !ans.empty() && num[ans.top()] && s[i] < ans.top()) {
vis[ans.top()] = 0;
ans.pop();
}
if (!vis[s[i]]) {
ans.push(s[i]);
vis[s[i]] = 1;
}
num[s[i]]--;
}
string now = "";
while (!ans.empty()) {
now += ans.top();
ans.pop();
}
reverse(now.begin(), now.end());
cout << now << endl;
return 0;
}