题干
原题网址:
https://leetcode.com/problems/queue-reconstruction-by-height/description/
难度
中等(Medium)
知识点
贪心算法
题干解析
一开始给你乱序的以pair为元素的一个vector,每个pair表示一个人,pair的第一个数表示此人的身高、第二个数表示在正确的顺序下,位于此人前面的人中身高比他高的人的个数。要你找到正确的顺序。
解题思路
我们要得到正确的顺序,就是要去掉冲突(当下前方较高人数,与正确顺序下前方较高人数相比,数值不一的人)。
利用贪心算法,每次对有冲突的人进行处理,若他的前方高于他的人多于正确值,那么就将此人前移,直至此人符合要求;若他的前方高于他的人少于正确值,那么就将此人后移,直至此人符合要求。因为每次移动一个人可能会影响其他人的正确值,所以要循环直至没有冲突才能停止算法。
这道题的直观思路不困难,不过具体实现上还是要细心一些。
代码
class Solution {
public:
vector<pair<int, int> > reconstructQueue(vector<pair<int, int> >& p) {
vector<pair<int, int> > people = p;
bool flag = 1; //标记是否还有冲突
while (flag) {
flag = 0;
int height, num;
//分别用来标志当前检查的人的高度,和正确顺序下排在他前面的个子比他高的人的个数
for (int i = 0; i < people.size(); i++) {
height = people[i].first;
num = people[i].second;
int j;
for (j = 0; j < i; j++) { //遍历此人现在前方的人
if (people[j].first >= height) { //若身高比第i个人高
num--; //误差数减一
}
}
j = i;
while (num < 0) { //若他的前方比他高的人多于正确的人数
flag = 1; //标记有冲突
//接下来把第i个人往前移动一位
pair<int, int> temp = people[j - 1];
people[j - 1] = people[j];
people[j] = temp;
if (people[j].first >= height) { //若身高高于此人
num++;
}
j--;
}
while (num > 0) { //若前方比他高的人小于正确人数
flag = 1; //标记有冲突
//接下来把第i个人往后移动一位
pair<int, int> temp = people[j + 1];
people[j + 1] = people[j];
people[j] = temp;
if (people[j].first >= height) {
num--;
}
j++;
}
}
}
return people;
}
};