假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。
拿到这道题没什么思路,看了大佬的题解才顿悟!
这道题主要是将原来的数组排序,首先按照第一个维度降序排列,然后第二个维度升序排列。
[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]经过排列之后变成 [5,0],[7,0],5,2],[6,1],[4,4],[7,1]
在这个排序问题上我纠结了很久,前几道题目就遇见过,主要是针对数组的自定义排序,需要实现Comparator接口的compare方法。具体实现为
Arrays.sort(people,new Comparator(){
@Override
public int compare(int[] people1,int[] people2){
if(people1[0] != people2[0]){
//第一个元素不相等时,按照第一个元素降序排列
return people2[0]-people1[0];
}else{
//第一个元素相等时,按照第二个元素升序排列
return people1[1]-people2[1];
}
}
});
排序完成之后,需要首先建立一个动态list来存储排序完成之后的元素。
这里通过遍历people,比较 people [i][1] 与 list.size() 的大小,如果 people [i][1] < list.size() ,则要把people [i] insert 进 list 的第 i 位置,反之,则直接追加到 list 的后面。
这里可以认为 如果一个人身高比他高的人数比队里已经排好队的人还多或者相等,那他就应该站在后面;如果身高比他高的人数小于队里已经排好队的人数,那他应该插在队里面的某个位置,这个位置就是第 i 位。
下面是一个例子:
在创建 list 的时候,ArrayList 或者LinkList 都可以,但是涉及到 add 或 insert 比较多的选择 LinkList会比较好,最后记得将 List 转换为数组。
class Solution {
public int[][] reconstructQueue(int[][] people) {
//按数组第一个元素降序,第二个元素升序排序
Arrays.sort(people,new Comparator(){
@Override
public int compare(int[] people1,int[] people2){
if(people1[0] != people2[0]){
//第一个元素不相等时,按照第一个元素降序排列
return people2[0]-people1[0];
}else{
//第一个元素相等时,按照第二个元素升序排列
return people1[1]-people2[1];
}
}
});
//新建一个arr,用于保存结果
ArrayList arr = new ArrayList<>();
for(int i = 0; i < people.length; i++){
if(arr.size() > people[i][1]){
//如果arr中元素个数大于第i人前面应有人数时,应该把people[i]插入people[i][1]的位置
arr.add(people[i][1],people[i]);
}else{
//如果arr中元素个数小于或等于第i人前面应有人数时,应该把people[i]插入arr尾部
arr.add(arr.size(),people[i]);
}
}
//将arr转化为数组
return arr.toArray(new int[arr.size()][]);
}
}