leetcode刷题之旅——406. Queue Reconstruction by Height

本文介绍了如何使用贪心算法解决LeetCode中的406题——根据身高重建队列。首先解释了题目的意思,然后通过一个例子展示了输入和输出。接着详细阐述了两种算法思路,重点讲解了先按身高降序排列,再按k值升序插入的方法,以确保较低复杂度。最后给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        本周和上周都讲了贪心算法,所以在leetcode上面挑了Greedy的算法题目来做。首先这道题目是所有贪心算法里面最简单的,是middle里面通过率最高的一道题目。

题目大意:

        给定一个队列,每一个元素代表一个人,每个人有两个属性,一个是他自身的身高,另一个是排在他前面比他身高要高的人数。本题给定这样一个vector,用来盛放每个人的个人信息,然后让你按照每个人的这两个元素对这个队伍进行排序。

例子:

        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]]:

算法:

        首先,这道题目是贪心算法中的一道题目,采用贪心算法来想问题。我考虑到,因为要求排序,我们就要有排序的依据,一个就是按照身高h来排,另一个就是人数k来排。我们先考虑按照身高来排序。

一、先按身高排序

        1、按升序排列:因为将个子矮的排到前面,所以后面还要考虑个子高的人的位置,这样做会很麻烦。

        2、按降序排列:因为先将个子高的安排好了,那么安排个子矮的同学的时候,不会影响个子高同学的k值。也就是说,安排好个子高的同学之后,使之满足k值,然后就不用担心个子高的同学的k值再变化,因为个子矮的人的位置再也不会影响个子高的人的k值了。

        所以说,先按降序排列,然后将个子高的同学先按k值升序排列。这样的话,个子矮的同学只需要按照k值insert进新的队列当中就可以了。因为个子矮的同学的k值固定,已经安排进队列的同学升高都比这个人要高,而且即将安排进来的人比他矮或者和他一样高但是k值比他大,所以他就可以放心的进入队列当中。只需要数到和他k值相同的同学个数,然后进入队列即可。这样,时间复杂度就是max{O(n),排序复杂度O(sort)}。

二、先按k值排序

        因为按照k值排序,我们一定是先考虑前面的同学,这样的话,我们先安排好k值为0的同学。如果k指相同,我们就按照身高升序排列。

        排好序之后,我们先安排k值为0的进入队列,然后再看k值为1的。我们设置一个变量count,让他遍历已经进入队列当中的同学,如果有身高大于将要进入同学的人,就加1,当count恰好比将要进入队列同学的k值大1的时候,我们就把这个同学放到使count变成k+1的那个同学前面去。这样做的复杂度就不如前面的那个好,因为进入一个同学就要遍历已经排好序的vector一遍。

因为第一种算法比较简单,我就按照第一种算法进行了实现。

代码如下:

class Solution 
{
public:
    static int cmp(const pair<int,int> a,const pair<int,int> b)
    {
        if(a.first==b.first)
        {
            if(a.second<b.second) return 1;
            else return 0;
        }
        else if(a.first<b.first) return 0;
        else return 1;
    }
    vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) 
    {
        vector<pair<int,int>> result;
        int n=people.size();
        sort(people.begin(),people.end(),cmp);
        int i=0;
        while(n!=0)
        {
            result.insert(result.begin()+people[i].second,people[i]);
            i++;
            n--;
        }
        return result;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值