LeetCode 406. Queue Reconstruction by Height 题解(C++)
题目描述
- 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.
- The number of people is less than 1,100.
示例
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]]
思路
自己的解法
- 这道题我自己的思路是首先使用一个isSet来标记这个pair是否已经被选过,每次从选择未被选过(即isSet为false)的pair中选取一个h最小的,记为temp,并记录该pair的位置(用pos记录)
- 第二步是根据上面选择出来的pair的w的值,选择该temp点最终存放的位置,这里根据w的值,需要找到该temp点前面刚好有w个未被标记的结点(即isSet为false)或虽然结点标记为true但它的h值与temp点相同的结点。
- 第三步交换两个结点即可,注意这里需要再次判断交换点位置是否被标记,若被标记则顺移到下一个结点。
最佳解法
- 最佳解法只需要一层for循环便可解答。首先将结点排序,h值大的结点排在前面,若两结点的h相同,则w小的结点排在前面。举个例子:本题的pair数组经过上述的排序后结果如下:
【7,0】【7,1】【6,1】【5,0】【5,2】【4,4】 - 之后依照上面排序后的顺序,依次根据w的值,选择插入位置,例子如下:
1.将【7,0】插入空数组
2.将【7,1】插入距离数组首元素为1的位置,此时数组为【7,0】【7,1】
3.将【6,1】插入距离数组首元素为1的位置,此时数组为【7,0】【6,1】【7,1】
4.将【5,0】插入距离数组首元素为0的位置,此时数组为【5,0】【7,0】【6,1】【7,1】
5.将【5,2】插入距离数组首元素为2的位置,此时数组为【5,0】【7,0】【5,2】【6,1】【7,1】
6.将【4,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)
{
vector<pair<int, int>> p = people;
bool isSet[1100] = {false};
pair<int, int> temp;
for (int i = 0; i < p.size(); ++i)
{
int pos;
temp.first = 1000000000;
for (int j = 0; j < p.size(); ++j)
{
if (isSet[j] == true)
{
continue;
}
if (temp.first > p[j].first)
{
temp = p[j];
pos = j;
}
}
int sum = 0;
int k = 0;
while (!(sum == temp.second))
{
if (isSet[k] == false)
{
++sum;
}
if (isSet[k] == true && p[k].first == temp.first)
{
++sum;
}
++k;
}
while (isSet[k] == true)
{
++k;
}
swap(p[pos], p[k]);
isSet[k] = true;
}
return p;
}
};
最佳解法
class Solution
{
public:
static bool myComp(const pair<int, int> &a, const pair<int, int> &b)
{
if (a.first == b.first)
return a.second < b.second;
return a.first > b.first;
}
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people)
{
vector<pair<int, int>> ret;
int n = people.size();
if (n == 0)
return ret;
sort(people.begin(), people.end(), myComp);
for (int i = 0; i < n; i++)
{
ret.insert(ret.begin() + people[i].second, people[i]);
}
return ret;
}
};
补充
这里是通过重写排序函数,对pair结点进行排序,另一种方法是通过使用lambda表达式实现。具体代码如下:
sort(people.begin(), people.end(), [](pair<int, int> a, pair<int, int> b)
{
return a.first > b.first || (a.first == b.first && a.second < b.second);
});