J
题目描述
You are given a sequence of n integers x = [x1,x2,...,xn] and an integer k . It is guaranteed that 1 ≤ xi ≤ k , and every integer from 1 to k appears in the list x at least once.
Find the lexicographically smallest subsequence of x that contains each integer from 1 to k exactly once.
Find the lexicographically smallest subsequence of x that contains each integer from 1 to k exactly once.
输入
The first line of input contains two integers n and k ( 1 ≤ k ≤ n ≤ 2 ∙105), where n is the size of the sequence, and the sequence consists only of integers from 1 to k .
Each of the next n lines contains a single integer xi( 1 ≤ xi ≤ k ). These are the values of the sequence X in order. It is guaranteed that every value from 1 to k will appear at least once in the sequence X .
Each of the next n lines contains a single integer xi( 1 ≤ xi ≤ k ). These are the values of the sequence X in order. It is guaranteed that every value from 1 to k will appear at least once in the sequence X .
输出
Output a sequence of integers on a single line, separated by spaces. This is the lexicographically smallest subsequence of X that contains every value from 1 to k.
描述:
找出一个子序列,使得这个子序列中包含给定序列中的所有字符一次,并且找到的子序列字典序要最小。
思路:
单调栈维护即可
入栈的情况:
1.当前元素比栈顶元素小
2.当前元素是最后一次出现了
弹出栈顶的情况:
1.当前栈顶比所选的元素大并且在后面还会出现
代码:
#include <iostream>
using namespace std;
const int N = 200010;
int a[N];
int n, k;
int stk[N], tt = 0;
int cnt[N];
bool st[N];
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i ++ )
{
cin >> a[i];
cnt[a[i]] ++ ;
}
stk[0] = -1; // 防止越界,当哨兵
for (int i = 0; i < n; i ++ )
{
if (tt == 0) // 只有第一个元素是这个情况,其余不可能存在栈空
{
stk[ ++ tt] = a[i];
st[a[i]] = true;
cnt[a[i]] -- ;
continue;
}
if ((a[i] < stk[tt] || cnt[a[i]] > 0) && !st[a[i]]) // 只要当前的栈顶元素满足就可以考虑入栈
{
while (stk[tt] > a[i] && cnt[stk[tt]] > 0) st[stk[tt -- ]] = false; // 当前栈顶大于a[i],并且栈顶元素不是最后一个就弹出
stk[ ++ tt] = a[i];
st[a[i]] = true;
cnt[a[i]] -- ;
continue; // 以上是插入栈顶的操作,这步continue是为了保证每次cnt[a[i]]只减一次
}
cnt[a[i]] -- ; // 如果当前的a[i]没有考虑入栈,次数也减1
}
for (int i = 1; i <= tt; i ++ ) cout << stk[i] << ' ';
puts("");
return 0;
}