假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。
public class 根据身高重建队列 {
public static void main(String[] args) {
int[][] people = {{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}};
int[][] res = reconstructQueue(people);
for(int i=0;i<res.length;i++)
{
System.out.println("["+res[i][0]+","+res[i][1]+"]");
}
}
public static int[][] reconstructQueue(int[][] people) {
int n = people.length;
if(n==0) return new int[0][0];
Arrays.sort(people, new Comparator<int[]>() {
@Override
public int compare(int[] person1, int[] person2) {
if(person1[0]==person2[0]){
return person1[1] - person2[1];
}
else
return person2[0] - person1[0];
}
});
List<int[]> list = new ArrayList<>();
/*for(int i=0;i< people.length;i++){
if(list.size()>people[i][1])
list.add(people[i][1],people[i]);
else
list.add(list.size(),people[i]);
}*/
for(int[] i :people)
list.add(i[1],i);
return list.toArray(new int[list.size()][]);
}
}
根据题意我们需要将每对数(每个人),按照元素1降序,元素2升序进行排序。因为按元素1降序排序排列的话,对于每个元素,在其之前的元素的个数,就是大于等于他的元素的数量,而按照第二个元素升序排序,不仅减少了插入的次数,还保证了正确性, 举个例子,在身高一样,k不一样的时候,譬如[5,2]和[5,3], 对于最后排完的数组,[5,2]必然在[5,3]的前面。所以如果遍历的时候[5,3]在前面,等它先插入完,这个时候它前面会有3个大于等于它的数组对,遍历到[5,2]的时候,它必然又会插入[5,3]前面(因为它会插入链表索引为2的地方),这个时候[5,3]前面就会有4个大于等于它的数组对了,这样就会出错。
在按照h和k排完序之后,我们需要将每对数按照题干进行插入,得到最后的结果。具体的操作就是按照前面所说的排序之后,按照每对数的k进行添加,因为我们是先排的高个子(h降序),再插入的矮个子,所以矮个子插入后,不会影响高个子的k。
PS:Comparator o1-o2 升序, o2-o1降序。