Early Orders

You are given a list of integersx1,x2,……,xn,and a number k.
It is guaranteed that each i from 1 to k appears in the list at least once.

Find the lexicographically smallest subsequence of x that contains
each integer from 1 to k exactly once.
在这里插入图片描述

示例1

输入

6 3
3
2
1
3
1
3
输出

2 1 3

示例2

输入
10 5
5
4
3
2
1
4
1
1
5
5
输出
3 2 1 4 5

题意

给你一个字符串,输出按字典顺序最小

x的子序列(保持输入的顺序,可以不连续),每个整数从1到k正好有一次。

代码

#include "stdio.h"
#include "string.h"
int a[999999],b[999999],c[999999],d[999999];
//a[]记录输入,b[]记录下每个数字最后出现的位子
//c[]标记数字,去重,d[]记录输出
int main()
{
	int i=1,n,m,j,k,l;
	scanf("%d %d",&m,&n);
	memset(b,0,sizeof(b));
	for(j=1;j<=m;j++)
	{
		scanf("%d",&a[j]);
		b[a[j]]=j;
		//记录下每个数字最后出现的位子
	}
	j=0;
	for(i=1;i<=m;i++)
	{
		if(c[a[i]]) continue;
		//c[]数组标记d[]中记录的数字,去重
		while(d[j]>a[i]&&b[d[j]]>i)
		//d[j]>a[i]:d[j]数字比a[i]数字大
		//b[d[j]]>i:d[j]数字在后面还会出现,不是最后一个
		{
			c[d[j--]]=0;//去除d[j]数字的标记
		}
		d[++j]=a[i];//a[i]记录到d[]中
		c[a[i]]=1;//标记a[i]数字
			
	}
	for(i=1;i<=j;i++)
	printf("%d ",d[i]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值