51nod 1255 字典序最小的子序列 (贪心 + stack)

简介: 51nod 1255 字典序最小的子序列 (贪心 + stack)

给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件:


1、包含字符串中所有出现过的字符各1个。


2、是所有满足条件1的串中,字典序最小的。


例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc。


输入

输入1行字符串S,所有字符均为小写,字符串的长度为L。(1 <= L <= 100000)。

输出

输出包含S中所有出现过的字符,每个字符各1个,并且字典序最小的S的子序列。

输入样例

babbdcc

输出样例

abdc


题目思路:用一个栈来储存答案,从左到右遍历一遍字符串,如果在栈中(有标记)直接continue。如果串中字符小于栈顶且字符串中还有栈顶元素则出栈,且取消标记。(这里应该用while循环,有可能栈中多个元素都要出栈),没有标记的直接进栈,标记。最后倒序输出就是了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
char s[maxn], ans[maxn];
int cnt[maxn], vis[maxn];
stack<char> st;
int main() {
  scanf("%s", s);
  int n = strlen(s);
  for (int i = 0; i < n; i++) {
    cnt[s[i]]++; //记录数量
  }
  for (int i = 0; i < n; i++) {
    cnt[s[i]]--;
    if (vis[s[i]]) { //如果该字符已经在栈中,直接跳过
      continue;
    }
    while (!st.empty() && st.top() > s[i] && cnt[st.top()] > 0) { //如果当前字符比栈顶元素要小,且当前栈顶元素可以在后面找的到,退栈(取消栈标记)
      vis[st.top()] = 0;
      st.pop();
    }
    st.push(s[i]);
    vis[s[i]] = 1;
  }
  int tot = 0;
  while(!st.empty()) {
    ans[++tot] = st.top();
    st.pop();
  }
  for (int i = tot; i >= 1; i--) {
    printf("%c", ans[i]);
  }
  printf("\n");
  return 0;
}
相关文章
|
7月前
|
算法 C++
【动态规划】【子序列除重】【C++算法】1987不同的好子序列数目
【动态规划】【子序列除重】【C++算法】1987不同的好子序列数目
|
7月前
|
C++
两种解法解决LCR 008. 长度最小的子数组【C++】
两种解法解决LCR 008. 长度最小的子数组【C++】
|
7月前
|
机器学习/深度学习 算法 测试技术
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
|
7月前
|
算法
【面试算法——动态规划 19】最长回文子序列&& (hard)让字符串成为回文串的最少插入次数
【面试算法——动态规划 19】最长回文子序列&& (hard)让字符串成为回文串的最少插入次数
|
7月前
|
算法 测试技术 C#
二分查找|差分数组|LeetCode2251:花期内花的数目
二分查找|差分数组|LeetCode2251:花期内花的数目
|
7月前
【每日一题Day157】LC1574删除最短的子数组使剩余数组有序 | 双指针 + 二分查找
【每日一题Day157】LC1574删除最短的子数组使剩余数组有序 | 双指针 + 二分查找
52 0
|
7月前
【每日一题Day122】LC1237找出给定方程的正整数解 | 双指针 二分查找
【每日一题Day122】LC1237找出给定方程的正整数解 | 双指针 二分查找
48 0
|
人工智能 算法
51nod 1202 子序列个数 (不重复子序列个数)
51nod 1202 子序列个数 (不重复子序列个数)
99 0
|
C++
C/C++每日一练(20230515) 区间和的个数、BST最近公共祖先、最接近元素
C/C++每日一练(20230515) 区间和的个数、BST最近公共祖先、最接近元素
102 0
|
人工智能
51nod 1624 取余最长路 (set 二分)
51nod 1624 取余最长路 (set 二分)
73 0