Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h,
k)
, where h
is the height of the person and k
is
the number of people in front of this person who have a height greater than or equal to h
.
Write an algorithm to reconstruct the queue.
Note:
The number of people is less than 1,100.
Example
Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]插入排序的思路
觉得我的代码麻烦了,因为既然是一个个插入我却按照选择高度最高的前提下k值最小的先插入,哎,doubi了,算法复杂度还是O(n^2)
如果事先先按高度和k值先排个序,然而复杂度似乎还是没下降,因为还是得插入
如果用分治算法...
每一个子队列满足这样性质:第i号位置的人person[i]的k值一定大于等于前面比ta高的数量
比如
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]可分为
[[7,0], [4,4], [7,1]]
[[5,0], [6,1], [5,2]]然后将[5,0][6,1][5,2]依次插入?这样的话合并复杂度是O(n^2),最后复杂度还是O(n^2)
So,有没有办法把合并的复杂度降到O(n),然后使得最后的复杂度降到O(n*log n)?
新生成一个空队列,然后
[7,0][5,0]中选择[5,0]放到队列第一个位置,然后
[7,0]与[6,1],谁在第二个位置?[6,1]不可能,所以第二个位置放[7,0],子队列和新生成的队列是这样的:
[[4,4], [7,1]]
[[6,1], [5,2]]
[[5,0],[7,0]]
[6,1]与[4,4],显然[6,1]放在第3个位置
然后
[[4,4], [7,1]]
[[5,2]]
[[5,0],[7,0],[6,1]]
然后
[[4,4], [7,1]]
[]
[[5,0],[7,0],[6,1],[5,2]]
然后
[]
[]
[[5,0],[7,0],[6,1],[5,2],[4,4],[7,1]]
那么合并的规则是?
[[4,4], [7,1]]
[[6,1], [5,2]]
[[5,0],[7,0]]
[6,1]与[4,4],显然[6,1]放在第3个位置
是经过判断[6,1]与[4,4]哪一个符合的,判断的复杂度又是O(n),这样合并的复杂度还是O(n^2)
有没有办法加强子队列必须满足的性质然后降低合并的复杂度?
还没想到办法
public class Solution {
public int[][] reconstructQueue(int[][] people) {
if(people.length == 0) return new int[0][0];
int[][] re_people = new int[people.length][people[0].length];
int people_num = people.length;
int person;
int max_h;
int k = people_num;
int count = 0;
for(count = 0; count < people_num; ++count){
max_h = 0;
k = people_num;
//select tallest person
for(person = 0; person < people_num; ++person){
if(people[person][0] > max_h){ //not visited
max_h = people[person][0];
}
}
int select_person = 0;
for(person = 0; person < people_num; ++person){
if(people[person][0] == max_h && people[person][1] < k){ //not visited & smallst k
k = people[person][1];
select_person = person;
}
}
person = select_person;
//insert the pseron
int p;
int place = 0;
int higher_person_num = 0;
for(p = 0; p < count; ++p){
if(people[person][1] == 0){
break;
}
if(re_people[p][0] >= people[person][0]){
++higher_person_num;
}
if(higher_person_num==people[person][1]){
++p;
break;
}
}
//shift
int i;
for(i = count; i >= p+1; --i){
re_people[i][0] = re_people[i-1][0];
re_people[i][1] = re_people[i-1][1];
}
re_people[p][0] = people[person][0];
re_people[p][1] = people[person][1];
people[person][0] = -1;// will not to be visited
}
return re_people;
}
}