LeetCode 406. Queue Reconstruction by Height 题解(C++)

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);
        });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值