首先我们发现对于不合法的情况:cnt(最大的相同的个数)*2-1>n
由于是字典序最小,我们肯定优先保证前面的越小越好,直接贪心
我们选择合法的时候最小的数字,置于当前位置。
注意:这里的合法不仅仅是考虑当前数字是否和前一个有重复,还要时刻满足cnt*2-1<=i。因为后面的没有排的也相当于一个序列,我们也要考虑他的合法性。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5;
int a[maxn];
map<int,int> cnt;int n;
set<pair<int,int> >s;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
cnt[a[i]]++;
}
for(map<int,int>::iterator it=cnt.begin();it!=cnt.end();it++)
{
s.insert(make_pair(it->second,it->first));
}
if((--s.end())->first*2-1>n)
{
puts("-1");
return 0;
}
int last=-1;
for(int i=1;i<=n;i++)
{
int x;
if((--s.end())->first*2-1==(n+1-i)) x=(--s.end())->second;
else
{
map<int,int>::iterator it=cnt.begin();
if(it->first==last) it++;
x=it->first;
}
s.erase(make_pair(cnt[x],x));
if(--cnt[x]) s.insert(make_pair(cnt[x],x));
else cnt.erase(x);//删去map中的元素
printf("%d%c", x, " \n"[i == n]);
last=x;
}
return 0;
}
这里使用set+map实现,个人认为这种方法比mutiset更优一些,灵活性更强。