Leetcode 406 Queue Reconstruction by Height
题目原文
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]]
题意分析
给定一组数据,均是pair类型,第一个元素为此人高度,第二个元素为站在他前面比他高的人数,根据这些条件重组这个队列。
解法分析
本题采用贪心思想,下面分析两种解法,第一种是我在做的时候想到的,第二个是讨论区大牛的思想。
解法1
对于最矮的人,他前面的人一定比他高,所以他的第二个参数代表了他所在的位置,对于第二矮的人,排除开最矮的人后,其他人都一定比他高,他的第二个元素为他所在的位置(总人数中去掉第一个人后),为了记录每个人最原始的位置,而不是人数减少后的位置(相应人的第二个参数),我构造一个vector a,初始长度为人数,初始化存储0到n-1这n个下标值,每去掉一个当前最矮人,就把a中相应位置人erase掉,对于高度相同的人有特殊处理,代码中会提及。C++代码如下:
class Solution {
private:
/* static bool compareS(pair<int,int> &a,pair<int,int> &b){//This compare function must be static, if it's defined out of main, it is naturally static
return a.second<=b.second;
}
static bool compareF(pair<int,int> &a,pair<int,int> &b){
return a.first<=b.first;
}*/
//vector<pair<int,int>>can supported by sort, first by "first", the "second"
public:
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
auto n=people.size();
sort(people.begin(),people.end());//按第一个和第二个元素升序排
//stable_sort(people.begin(),people.end());
int i;
vector<int> a;
vector<pair<int,int>> res(n);
for(i=0;i<n;i++){
a.push_back(i);//构造存储原有下标值的vector
}
int count=0;//记录相同高度人的出现次数
int last=0;//记录上一个人的高度
for(i=0;i<n;i++){
if(last!=people[i].first){
count=1;
res[a[people[i].second]]=people[i];//a已经缩短了,用people[i]的second提取a中存储的原有下标,将people[i]存入
a.erase(a.begin()+people[i].second);
last=people[i].first;
}
else{
res[a[people[i].second-count]]=people[i];//因为相同高度的人会算在second中
a.erase(a.begin()+(people[i].second-count));
count++;
last=people[i].first;
}
}
return res;
}
};
解法2
此解法将身高由高到低排,相同身高的人second从低往高排,直接往vector<pair<int,int>> 里按顺序插入,用insert函数,c++代码如下:
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
auto comp = [](const pair<int, int>& p1, const pair<int, int>& p2)
{ return p1.first > p2.first || (p1.first == p2.first && p1.second < p2.second); };
sort(people.begin(), people.end(), comp);
vector<pair<int, int>> res;
for (auto& p : people)
res.insert(res.begin() + p.second, p);
return res;
}
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
排序后
[[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]]
插入第一个元素后res为:
[7,0]
在迭代器res.begin()+1之前插入[7,1],得到res为:
[7,0][7,1]在迭代器res.begin()+1之前插入[6,1],得到res为:
[7,0],[6,1],[7,1]
注意到当要插入高度为6的人时,只有高度为七的人可能比他高,使得其second不为1,所以它的second准确指出了他应该插入的位置。