【leetcode】406. 根据身高重建队列(按身高降序排序,依次取出高个放到合适位置,list容器,辅助函数advance(it, n) )

题目

假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

注意:
总人数少于1100人。

示例
输入:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
输出:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

思路

参考leetcode清晰思路
核心思路非常简单:

  1. 先把人员按身高降序排序,然后依次取出身高更高的放到合适位置。这是要防止后插入的人员影响先放好的人员的位置(根据k的定义,后插入的矮个子无论插在哪里,对高个都是没有影响的)
  2. 那怎么为每个人插到合适位置呢?因为每次排入新人员[h,k]时,已处于队列的人身高都>=h,所以新人员的插入位置就是k。(k是排在这个人前面且身高大于或等于h的人数)

具体实现细节:

  • 排序:按身高降序排序,相同身高按k升序排序
  • 新队列选择什么容器?由于需要频繁的插入,所以建议用链表list,最后重建为二维vector再返回。
  • 但是list的迭代器不支持随机访问,如何快速定位要插入的位置呢?借助STL迭代器辅助函数advance(it, n):it 表示某个迭代器,n 为整数。该函数的功能是将 it 迭代器前进或后退 n 个位置。

代码

class Solution {
public:
    bool cmp(vector<int> a, vector<int> b){
        if( a[0] == b[0] ){
            return a[1] <= b[1];
        }
        return a[0] > b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        if( people.size() <= 1 ){
            return people;
        }
        vector<vector<int>> anws; //(h身高, k前面>=的高个人数)
        //按身高降序排序,相同身高按k升序排序,然后依次遍历,去判断插到新队列的合适位置
        //sort(people.begin(), people.end(), cmp);
        sort(people.begin(), people.end(), [](const vector<int>&l, const vector<int>&r){
                return l[0]==r[0] ? l[1] <= r[1] : l[0] > r[0];
        });
        //新队列
        list<vector<int> > lis;
        for(int i=0; i<people.size(); i++){
            //插入位置为k
            int k = people[i][1];
            auto it = lis.begin();
            advance(it, k); // 迭代器往后移动k个位置
            lis.insert(it, people[i]); //在指定迭代器位置插入新元素
        }
        return vector<vector<int>>(lis.begin(), lis.end()); //拷贝构造
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值