题目
假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。
注意:
总人数少于1100人。
示例
输入:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]输出:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
来源:力扣(LeetCode)
解
首先我们大概猜出,应该是要把k=0的放前面,然后k!=0的,再按照k值放入相应位置。那么问题就在,在一个无序数组中,我们怎么保证本次放入的位置,不受后序放入的影响?如果插入了一个值,>=后面已放入的值,那么就错误了。
所以,我们为数组排序。按照从高到低去排序,这样我们从头遍历的时候,每一次新进入的都不影响原先的元素(因为<),如果是=呢?那么肯定就是谁的k小谁放前面了,否则就无法组成正确的数组(k大的放前面满足要求,k小的放后面,那小k必然不能满足(大k+1)的要求)。那么我们每次插入时就按照其需要的k值插入即可,因为就能让其满足>=h的元素个数为k。那么如果出现先插入的k过大的(即已有元素数量不能满足k的),则必然是错误数组,因为后续的元素都势必小于或等于(且k更大)本元素。
时间上达到了O(n^2),空间上也是O(n),所以这道题的解暂时不算优。
class Solution {
public int[][] reconstructQueue(int[][] people) {
//排序
Arrays.sort(people,new Comparator<int[]>(){
public int compare(int[] people1, int[] people2){
if(people1[0]!=people2[0]){
return people2[0]-people1[0];
}else{
return people1[1]-people2[1];
}
}
});
//顺序插入
List<int[]> rs = new ArrayList<int[]>();
for(int[] p : people){
rs.add(p[1],p);
}
//注意java中int[]就是一个对象
return rs.toArray(new int[rs.size()][]);
}
}