2021.08.08修改了示例用例的过程(原来写错了)
题目
https://leetcode-cn.com/problems/queue-reconstruction-by-height/
分析
(套路):一般这种数对,还涉及排序的,根据第一个元素正向排序,根据第二个元素反向排序,或者根据第一个元素反向排序,根据第二个元素正向排序,往往能够简化解题过程。
在本题目中,我首先对数对进行排序,按照数对的元素 1 降序排序,按照数对的元素 2 升序排序。原因是,按照元素 1 进行降序排序,对于每个元素,在其之前的元素的个数,就是大于等于他的元素的数量,而按照第二个元素正向排序,我们希望 k 大的尽量在后面,减少插入操作的次数。
后面的人既然不会对第 i 个人造成影响,我们可以采用「插空」的方法,依次给每一个人在当前的队列中选择一个插入的位置。也就是说,当我们放入第 i 个人时,只需要将其插入队列中,使得他的前面恰好有 k_i个人即可。
//用例
复杂度
时间复杂度:O(n^2) ,其中 n 是数组people 的长度。我们需要 O(nlogn) 的时间进行排序,随后需要 O(n^2)的时间遍历每一个人并将他们放入队列中。由于前者在渐近意义下小于后者,因此总时间复杂度为 O(n^2)。
空间复杂度:O(logn),即为排序需要使用的栈空间。
代码
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people,new Comparator<int[]>(){
public int compare(int[] person1, int[] person2){
if(person1[0]!=person2[0])
return person2[0]-person1[0];//h降序
else
return person1[1]-person2[1];//k升序
}
});
ArrayList<int[]> res=new ArrayList<>();
for(int[] person:people){
res.add(person[1],person);
}
return res.toArray(new int[res.size()][]);
}
}