Leetcode算法学习日志-406 Queue Reconstruction by Height

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准确指出了他应该插入的位置。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值