2024 7/18 7.30起床来实验室,领导视察。这两天都在干组内的事,没有做题,还有一个小因素是被399题劝退,冗长的代码打消了我做题的念头,今天的题还是看了题解,发现代码不长才做的,那么开始吧!
1、题目描述
2、算法分析
- 首先我们来看看这题目到底说了个啥:
[h,k]
,h
是身高看得懂。问题是为啥k
这个数这么奇怪。是不是!- 这么说试着理解一下,
k
代表的是,现在这个队里,自己前面的人里面,h
比自己大或与自己相等的人的个数。 - 好比
[7,1]
,代表,自己高7
,排在自己前面,且比自己高或相等的只有一个人。 - 而
[7,0]
意思是,排在自己前面的人,没有比自己高的!
输入: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
输出:
[[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]]
这里直接cv
的官解下面的评论,感谢《孤舟蓑笠翁》,anyway,理解题意后,怎么排序呢?
算法思路详解:
排序步骤:
首先,根据题目要求,我们需要按照特定规则对 people 数组进行排序:
首先按照身高 h 进行降序排列。即若 o1[0] > o2[0]
,则 o1
排在 o2
前面;若 o1[0] < o2[0]
,则 o1
排在 o2
后面。
若身高相同(o1[0] == o2[0]
),则按照前面比他们高或等高的人数 k 进行升序排列。即若 o1[1] < o2[1]
,则 o1
排在 o2
前面;若 o1[1] > o2[1]
,则 o1
排在 o2
后面。
这个排序步骤保证了在后续的重建队列过程中,每次插入操作都是在正确的位置进行的,不会破坏已经排好序的队列顺序。
重建队列步骤:
使用 LinkedList<int[]> list
来存储重建后的队列。
遍历经过排序后的 people 数组。
对于每个人 person,根据他们的 person[1]
值(即前面比他们高或等高的人数),将他们插入到 list 中的对应位置。
在 LinkedList 中,list.add(index, element)
方法可以将 element
插入到指定 index
处。
因为 people 数组已经按照规则排序过,插入操作会按照规则将每个人正确地放置在队列中。
返回结果:
最后,将 LinkedList 转换为二维数组并返回。
3、代码
public int[][] reconstructQueue(int[][] people) {
// 1. 根据身高降序排列,若身高相同则按照前面比他们高或等高的人数升序排列
Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);
// 使用 LinkedList 存储重建后的队列
LinkedList<int[]> list = new LinkedList<>();
// 2. 遍历排序后的数组
for(int[] i : people){
// 将当前人插入到已排序的队列中,按照他前面的人数作为索引位置
list.add(i[1], i);
}
// 将 LinkedList 转换为二维数组并返回
return list.toArray(new int[list.size()][]);
}
举例说明:
假设输入people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
排序
根据身高k
降序排列,若身高相同则按照前面比他们高或等高的人数h
升序排列:
重建队列
将当前人插入到已排序的队列中,按照他前面的人数作为索引位置:
4、复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n 是数组 people 的长度。我们需要 O(nlogn) 的时间进行排序,随后需要 O ( n 2 ) O(n^2) O(n2)的时间遍历每一个人并将他们放入队列中。由于前者在渐近意义下小于后者,因此总时间复杂度为 O ( n 2 ) O(n^2) O(n2)>
- 空间复杂度:O(logn)。
okok
拜拜啦!