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;
}
相关文章
|
3月前
|
C++
两种解法解决LCR 008. 长度最小的子数组【C++】
两种解法解决LCR 008. 长度最小的子数组【C++】
|
3月前
|
算法 测试技术 C#
【单调栈】LeetCode2030:含特定字母的最小子序列
【单调栈】LeetCode2030:含特定字母的最小子序列
|
3月前
|
算法
DAY-7 | 牛客-BM21 寻找旋转数组的最小元素:二分法分治思想真的很可靠
这是一个关于编程题目的摘要:题目是牛客网上的&quot;BM21 旋转数组的最小数字&quot;,要求找到旋转数组中的最小数字。题解介绍了使用二分查找算法来解决此问题,因为其时间复杂度优于暴力搜索的线性时间复杂度。二分查找的核心是通过比较中间元素与右端元素的大小,不断缩小搜索范围,最终找到最小值。代码示例展示了如何实现这个算法。总结中强调了二分查找适用于部分有序数组,并指出了解决这类问题的关键在于理解数组的二段单调性。
37 1
|
3月前
|
机器学习/深度学习 算法 测试技术
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
【线段树】【区间更新】2916. 子数组不同元素数目的平方和 II
|
3月前
|
算法
【面试算法——动态规划 19】最长回文子序列&& (hard)让字符串成为回文串的最少插入次数
【面试算法——动态规划 19】最长回文子序列&& (hard)让字符串成为回文串的最少插入次数
|
3月前
【每日一题Day157】LC1574删除最短的子数组使剩余数组有序 | 双指针 + 二分查找
【每日一题Day157】LC1574删除最短的子数组使剩余数组有序 | 双指针 + 二分查找
25 0
|
3月前
【每日一题Day122】LC1237找出给定方程的正整数解 | 双指针 二分查找
【每日一题Day122】LC1237找出给定方程的正整数解 | 双指针 二分查找
31 0
|
8月前
|
算法 测试技术 C#
C++ 算法:区间和的个数
C++ 算法:区间和的个数
|
10月前
|
算法 C++
剑指offer(C++)-JZ40:最小的K个数(算法-排序)
剑指offer(C++)-JZ40:最小的K个数(算法-排序)
|
人工智能 算法
51nod 1202 子序列个数 (不重复子序列个数)
51nod 1202 子序列个数 (不重复子序列个数)
80 0