题目1 : 分隔相同整数
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个包含N个整数的数组A。你的任务是将A重新排列,使得任意两个相等的整数在数组中都不相邻。
如果存在多个重排后的数组满足条件,输出字典序最小的数组。
这里字典序最小指:首先尽量使第一个整数最小,其次使第二个整数最小,以此类推。
输入
第一行包含一个整数N,表示数组的长度。(1 <= N <= 100000)
第二行包含N个整数,依次是 A1, A2, ... AN。(1 <= Ai <= 1000000000)
输出
输出字典序最小的重排数组。如果这样的数组不存在,输出-1。
样例输入
4 2 1 3 3
样例输出
1 3 2 3
import java.util.*;
import java.io.*;
public class Main{
public static void main(String[] args)throws Exception {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
TreeMap<Integer,Integer> numbers = new TreeMap<Integer,Integer>();
int n = sc.nextInt();
int temp;
for(int i = 0; i < n; ++i){
temp = sc.nextInt();
if(numbers.containsKey(temp)){
numbers.replace(temp,numbers.get(temp)+1);
}
else{
numbers.put(temp,1);
}
}
boolean cantFound = false;
for(Map.Entry<Integer,Integer> pair: numbers.entrySet()){
if(pair.getValue() > (n+1)/2){
System.out.println(-1);
cantFound = true;
break;
}
}
if(cantFound){
continue;
}
int last = -1;
int key;
Integer higherKey,higherValue;
ArrayList<Integer> result = new ArrayList<Integer>(n);
while(numbers.size() > 0){
key = numbers.firstKey();
if(key != last){
addKey(key,result,numbers);
last = key;
}
else{
higherKey = numbers.higherKey(key);
if(higherKey == null){
findPlace(key,result,numbers);
}
else{
addKey(higherKey,result,numbers);
last = higherKey;
}
}
}
System.out.printf("%d",result.get(0));
for(int i = 1; i < result.size(); ++i){
System.out.printf(" %d",result.get(i));
}
System.out.printf("\n");
}
}
public static void addKey(int key, ArrayList<Integer> result, TreeMap<Integer,Integer> numbers){
result.add(key);
int value = numbers.get(key);
if(value > 1){
numbers.replace(key,value-1);
}
else{
numbers.remove(key);
}
}
public static void findPlace(int key, ArrayList<Integer> result, TreeMap<Integer,Integer> numbers){
//the elements left in numbers are the same number,so insert them one by one.
int insertPos = result.size()-2;//size will change after insert operation,be careful.
int amountOfKey = numbers.get(key);
int replacePos = result.size()-2;
for(int i = 0; i < amountOfKey; ++i){
while(insertPos > 0){
if(result.get(insertPos) != key && result.get(insertPos-1) != key){
if(result.get(insertPos) > result.get(insertPos-1)){
for(int j = result.size()-2; j > insertPos; --j){
if(result.get(j) == result.get(insertPos-1)){
int temp = result.get(j);
result.set(j,result.get(insertPos));
result.set(insertPos,temp);
break;
}
}
}
numbers.replace(key,numbers.get(key)-1);
result.add(insertPos,key);
insertPos = insertPos - 1;
break;
}
--insertPos;
}
}
//the last one(if exist) to be insert in first place.
//only if numbers.get(k) == (n+1)/2
if(numbers.get(key) > 0){
result.add(0,key);
}
numbers.remove(key);
}
}