LeetCode 406. Queue Reconstruction by Height (贪心)

题目意思:

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

贪心思路:

1、首先确定第一个,首先第一个的 k 必定等于0,可以举反例,k = 1的不可能在第一个(这个很好理解因为k等于1说明前面有一个),所以在 k 等于0找 h 最小的为第一个。

2、设立一个标记数组,每拿一个,需要比它小或相等的数+1, 比如说我第一个拿了 [ 5, 0 ],那比5小和相等的数只有 4 和 5,那在数组中把 flagNum[4]+=1; flagNum[5]+=1;

3、遍历一遍数组,找出满足条件也就是 flagNum[ people[ i ][ 0 ] ] = people[ i ][ 1 ] 的数并且之前没有选择过,有可能有几个数都满足,那么给出一个贪心选择的策略  就是选择 h-k 最小的那个,比如例子中 [ 7, 0 ] 后面同时满足的应该有 [ 5, 2 ]和 [ 6, 1 ],h越小越在前面,k越大约在前面(也就是h-k 最小)。

class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        set<int> s;
        //定义是否取过的标记数组
        int flag[people.size() + 5];
        memset(flag, 0, sizeof(flag));
        //用于记录当前每个数字前面有多少个
        int flagNum[1000000];
        memset(flagNum, 0, sizeof(flagNum));
        //结果集
        vector<vector<int >> res;
        //判断下界
        if(!people.size()) return res;
        //第一遍先找出第一个
        int tmpMin = INT_MAX, tmpIndex = 0;
        vector<int > tmpFirst;
        for(int i = 0; i < people.size(); i++){
            if(people[i][0] < tmpMin && people[i][1] == 0){
                tmpMin = people[i][0];
                tmpFirst = people[i];
                tmpIndex = i;
            }
            s.insert(people[i][0]);
        }
        res.push_back(tmpFirst);
        for(int num: s) {
            if(num <= tmpFirst[0]) flagNum[num] += 1;
        }
        flag[tmpIndex] = 1;
        while(res.size() < people.size()){
            //如果条件都符合,就找前-后越小的
            int min = INT_MAX;
            vector<int > flagVector;
            int index;
            for(int i = 0; i < people.size(); i++){
                if(flag[i] == 0 && people[i][0]-people[i][1] < min && flagNum[people[i][0]] == people[i][1]){
                    min = people[i][0]-people[i][1];
                    flagVector = people[i];
                    index = i;
                }
            }
            res.push_back(flagVector);
            for(int num: s) {
                if(num <= flagVector[0]) flagNum[num] += 1;
            }
            flag[index] = 1;
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_我走路带风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值