[LeetCode]406. Queue Reconstruction by Height 解题报告
来源:互联网 发布:html合并单元格编程题 编辑:程序博客网 时间:2024/06/05 10:17
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从小到大排,相同的k按照h从小到大排。
方法一,我的思路就是,对每一个People,排在他前面的人比他个字高的人的个数(排序完成以后,第一个人的位置肯定是对的的,因为假如第一个不对的话,不可能有人比他高, 但是个数又比他少的了,这里用反证法可以得出)。如果数到他的时候,刚刚好,那么他的位置就不需要改变;如果还没到他的时候,个数就已经够了,那么就再往下数一个比他高的,把他插入到这个人前面就可以了。例如:
排序好以后的数列是:50,70,61,71,52,44
- 检查50,不变
- 检查70,不变
- 检查61,有1个70符合,不变。
- 检查71,有1个70符合,不变。
- 检查52,50符合,70符合,61符合,61已经是第3个了,所以把52插入到61前面,当前序列是50,70,52,61,71,44。(这个地方需要注意的是,将52插入到61前面,并不影响61的相对位置,因为只会把一个矮的插到高的前面,对高的没有影响,不会把高的插到矮的前面)
上面的思路结果正确,但是提交以后超时,它的复杂度大概是nlogn+n^2=n^2
LinkedList<People> listPeople = new LinkedList<People>();public int[][] reconstructQueue(int[][] people) {for (int[] is : people) {listPeople.add(new People(is[0], is[1]));}Collections.sort(listPeople);for (int i = 0; i < listPeople.size(); i++) {int nBigger = 0;People pCurrent = listPeople.get(i);for (int j = 0; j < i; j++) {if (listPeople.get(j).nH >= pCurrent.nH) {nBigger++;}if (nBigger > pCurrent.nK) {listPeople.remove(i);listPeople.add(j, pCurrent);break;}}}for (int i = 0; i < people.length; i++) {people[i][0]=listPeople.get(i).nH;people[i][1]=listPeople.get(i).nK;}return people;}
方法二,看了网友的解答以后,发现其实后面不需要对每个进行排序,利用上面提到了的,排好序的第一个位置肯定是固定的,因此,每次取出第一个位置,再排序,直到所有的都取出来。另外,在取出第一个的时候,需要对后面的进行遍历,如果存在比当前高的人,那么就对当前的数量减一即可,这样才能保证每次排序的正确性。例如:第一个取出的50,那么当遍历到52时,需要对2减一,在下一次排序的时候,排的就是51。代码如下:
public class Solution { List<int[]> listPeople = new LinkedList<int[]>();public int[][] reconstructQueue(int[][] people) {for (int[] p : people) {listPeople.add(new int[] { p[0], p[1], p[1] });}int[][] nArrAns = new int[people.length][];int nIndex = 0;while (listPeople.size() > 0) {Collections.sort(listPeople, new Comparator<int[]>() {public int compare(int[] a, int[] b) {if (a[1] == b[1]) {return a[0] - b[0];}return a[1] - b[1];}});nArrAns[nIndex] = new int[] { listPeople.get(0)[0], listPeople.get(0)[2] };listPeople.remove(0);for (int[] nCurPeople : listPeople) {if (nCurPeople[0] <= nArrAns[nIndex][0]) {nCurPeople[1] -= 1;}}nIndex++;}return nArrAns;}}
提交以后,第二种方法在所有方法中排比较后的位置,因此应该还有速度更快的方法。
事实上,第二种方法的复杂度也相当高,大致是nnlogn+n=n^2logn.
看起来这种方法的复杂度应该比第一个还高,但是我们计算一下具体的系数。
方法一:nlogn+(1+n)n/2=n(n/2+logn+1/2)
方法二:1log1+2log2+...+nlogn+(1+n)n/2
前面的数列无法求和,但是可以用斯特林公式逼紧,但是方法二的复杂度明显大于方法一。
总的来说,第一种方法理论复杂度比第二种方法低,第二种方法思考起来更加直观。
我猜想,之所以第一种方法超时,有两个原因:1.可能是因为复杂的插入操作造成的,方法二只有自减操作,这和LeetCode测试用例也有关,可能存在一些非常极端的例子;2.构造的People类有些复杂,new对象,不如直接使用int数组快。
0 0
- LeetCode 406. Queue Reconstruction by Height 解题报告
- [leetcode] 406. Queue Reconstruction by Height 解题报告
- Leetcode解题报告:406. Queue Reconstruction by Height
- LeetCode解题报告 406. Queue Reconstruction by Height [medium]
- [LeetCode]406. Queue Reconstruction by Height 解题报告
- [Leetcode] 406. Queue Reconstruction by Height 解题报告
- Leetcode 406. Queue Reconstruction by Height 排队重构 解题报告
- LeetCode—406. Queue Reconstruction by Height
- [LeetCode]406.Queue Reconstruction by Height
- LeetCode 406. Queue Reconstruction by Height
- [LeetCode] 406. Queue Reconstruction by Height
- Leetcode 406. Queue Reconstruction by Height
- LeetCode 406. Queue Reconstruction by Height
- LeetCode笔记:406. Queue Reconstruction by Height
- 【LeetCode】 406. Queue Reconstruction by Height
- [leetcode]406. Queue Reconstruction by Height
- [Leetcode] 406. Queue Reconstruction by Height
- LeetCode 406. Queue Reconstruction by Height
- LeetCode-14. Longest Common Prefix
- 树和二叉树
- 欢迎使用CSDN-markdown编辑器
- Jan 3rd - 新的一年,新的开始
- C++ 排序函数 sort(),qsort()的用法
- [LeetCode]406. Queue Reconstruction by Height 解题报告
- web前端面试题整理(程序篇)
- OpenGL环境搭建
- 《C++ API》
- 如何限制textarea标签文本长度
- 过年结束,开始上班
- 邮件名固定格式
- java 算法
- 《连载 - 物联网框架ServerSuperIO教程》- 15.数据持久化接口的使用。附:3.2发布与版本更新说明。