该大佬
解题思路以及解题代码都非常精妙,遂记录于此学习。
一、解题思路:
将人群的身高按降序排列,k按升序排列。
然后创建一个有序的list,将每个人按其k值插入list,全部插入完成以后即可得到结果。
解释:由于前面的人数已经是按降序排列了,所以插入到位置k后,前面一定有k个大于等于其身高的人。前提是k按升序排列!!
// [7,0], [7,1], [6,1], [5,0], [5,2], [4,4]
// 再一个一个插入list。
// [7,0]
// [7,0], [7,1]
// [7,0], [6,1], [7,1]
// [5,0], [7,0], [6,1], [7,1]
// [5,0], [7,0], [5,2], [6,1], [7,1]
// [5,0], [7,0], [5,2], [6,1], [4,4], [7,1]
// 排序结束,大功告成
二、解题核心代码
public static int[][] reconstructQueue(int[][] people) {
// 排序
Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);
// 创建一个有序链表
List<int[]> list = new LinkedList<>();
// 插入list
for(int[] i : people){
// 这里插入的位置一定是前面都插入过的(排序后已经满足这个条件,不然会报错)
list.add(i[1], i);
}
// 重新将list转为数组,并返回
return list.toArray(people);
}
三、二维数组排序
Arrays.sort 函数真的很精妙
对于一维数组来说,如果要升序排列,可以直接用 Arrays.sort 函数排序,但是其他情况,需要自己定义一个排序函数,定义方式如下:
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// 这里是升序,如果是o2[0] - o1[0] 就是降序,总之前减后是升序,后减前是降序
return o1[0] - o2[0];
}
});
如果需要二重排序,即排序的某值相等时,按另外的标志排,写法可以参考如下:
arr初始:[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]
Arrays.sort(arr, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// 含义是arr数组某行第一个值不相等时,按降序排。否则,比较第二个值,按升序排。
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0];
}
});
输出arr:[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]
四、list排序
list排序用的是Collections.sort,而数组排序用的是Arrays.sort
List<int[]> list = new LinkedList<>();
Collections.sort(list, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
五、list转数组
// 方法一,arr是一个已经定义好的数组,注意维度要一致
list.toArray(arr);
// 方法二
int[][] arr = list.toArray(new int[list.size()][list.get(0).length]);
六、数组转list
对于 String 类型可以按如下转:
String[] arr = {"hello", "world", "test"};
List<String> list = Arrays.asList(arr);
对于 int 类型可以按如下转:
int[] arr = {1, 2, 4, 1, 2};
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());