写在前面
第二遍刷leetcode,发现还是有一些题目并未完全理解透,二刷能够解决一部分问题,关键还是一道题的思想本身要搞明白。对于本题来讲,是一个插入排序的特殊变形。
题目描述
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]]
思路分析
一个插入排序思想的应用。每对数靠前位置的数代表这个人的身高,后面的数代表在已排好序的数组中,在这个人前面身高大于等于当前身高的人的个数,其实就是数对的个数。这题采用插入排序的思想解决,我们先按身高对数组进行排序,得到按身高分组的序列,数对后一个数字就表示插入的位置,这样最后得到的序列就是满足条件的序列。以上面的例子来进行说明,排好序的数组如下:
[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]
首先插入[7,0],[7,1] 我们得到的序列为[7,0],[7,1]
在这个新序列中,数的大小和位置都满足要求。
接着插入[6,1],我们得到[7,0],[6,1],[7,1]
6的前面只有一个数,即[7,0]
接着插入[5,0],[5,2],我们得到[5,0],[7,0],[5,2],[6,1],[7,1]
[5,0]要先于[5,2]插入,否则,先插入[5,2],再插入的[5,0]会使[5,2]不满足要求。
接着插入[4,4],我们得到[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]
插入排序得到正确保证的原因在于,因为后插入的数字小于先插入的序列,因此后插入的数字无论插在哪个位置,都不会对已存在的序列造成任何影响。插入排序的正确性因此得到保证。
代码实现
class Solution {
public:
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
// 插入排序
sort(people.begin(),people.end(),[](const pair<int,int>& lhs, const pair<int,int>&rhs)->int {
if(lhs.first == rhs.first) return lhs.second<rhs.second;
return lhs.first>rhs.first;
});
vector<pair<int,int>> retVec;
for(auto& val:people) retVec.insert(retVec.begin()+val.second,val);
return retVec;
}
};