406. 根据身高重建队列 - 力扣(LeetCode)
本题有两个维度,h和k,
看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。
k维度:
从小到大排
(因为k代表个数)
h维度:
从大到小排
(h代表身高,题目中说“身高更高或者相同的人排在前”,所以从大到小)
若h相同,k应该从小到大排
实操后发现:如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。
身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。
此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!
那么只需要按照k为下标重新插入队列就可以了
people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]
插入的过程:
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
class Solution {
public int[][] reconstructQueue(int[][] people) {
//按照身高从大到小排序
//a[0]第一个人的身高,a[1]第一个人前面的k
//b[0]第二个人的身高,b[1]第二个人前面的k
Arrays.sort(people,(a,b)->{
if (a[0]==b[0]) return a[1]-b[1];
return b[0]-a[0];
});
//按照k从小到大重新插入
LinkedList perpmute = new LinkedList<>();
for (int[]p:people){
perpmute.add(p[1],p);
}
return perpmute.toArray(new int[people.length][]);
}
}
Arrays.sort
`使用了一个自定义的比较器,它接受两个参数a和ba
`和`b
`代表了`people
`数组中的两个元素,每个元素都是一个一维数组,表示一个人的身高和前面的人数。a[0]
`表示第一个人的身高,`a[1]
`表示第一个人的前面人数。b[0]
`表示第二个人的身高,`b[1]
`表示第二个人的前面人数。因此,`(a, b) -> {...}
`中的比较逻辑根据这些元素的身高和前面的人数进行排序。
a
`和`b
`的身高相同(`a[0] == b[0]
`),则`a[1] - b[1]
`表示根据前面的人数升序排列。( a - b 是升序)a
`和`b
`的身高不同,则`b[0] - a[0]
`表示根据身高降序排列。( b - a 是降序)LinkedList
`来重新排列`people
`数组中的元素 //按照k从小到大重新插入
LinkedList perpmute = new LinkedList<>();
for (int[]p:people){
perpmute.add(p[1],p);
}
`perpmute
`是一个`LinkedList
`,`int[]
`表示这个链表中存储的是整型数组。
`for (int[] p : people)
` 这行代码是一个增强型for循环,用于遍历`people
`数组中的每个元素,其中`p
`代表数组`people
`中的每个元素。
在循环中,`perpmute.add(p[1], p)
` 的作用是将数组`p
`插入到链表`perpmute
的指定位置`p[1]
`。实际上是根据排好序的规则来插入元素。
这里`p[1]
`表示当前人前面的人数,所以实际上是在链表中按照前面的人数进行插入操作。而`p
`代表当前的人。
LinkedList
`是因为在插入操作中,`LinkedList
`的插入效率更高。当按照`k
`值从小到大重新插入时,使用`LinkedList
`能够更有效地支持这一操作。因为`LinkedList
`的插入操作的时间复杂度为O(1),而数组的插入操作的时间复杂度为O(n),因此选择`LinkedList
`能够更快速地完成按照`k
`值重新插入的操作。
尽管使用`LinkedList
`进行插入操作更高效,但在最后需要将结果转换成`int[][]
`类型。这是因为方法的返回类型是`int[][]
`,因此需要将`LinkedList
`转换为`int[][]
`,以符合方法的返回类型要求。
people
`数组进行排序的时间复杂度为O(nlogn),其中n是`people
`数组的长度。LinkedList
`进行插入操作,总共需要进行n次插入操作。每次插入操作的时间复杂度为O(1)。因此,总体时间复杂度为O(nlogn+n),简化后为O(nlogn)。
LinkedList
`中的元素,空间复杂度为O(n)。因此,总体空间复杂度为O(n)。