【LeetCode406】-根据身高重建队列

方法一

实现思路

规律 : 可以先从高度最小的开始安排顺序
例:输入为people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
一、 先将数组按照高度升序排序,当高度相同时按前面人数值升序排序)
处理后people = [[4,4],[5,0],[5,2],[6,1],[7,0],[7,1]]
二、 创建数组存储满足当前位置前面人数为i的下标值
如:book[2]=2 代表在数组2位置处,前面有两个元素大于当前值
所以初始化book[i]=i
三、 遍历people数组
四、 更新book数组
具体更新book细节,结合例子来看

在这里插入图片描述[4,4]现在被放在了下标4的位置,开始更新book值
在这里插入图片描述经排序之后先处理的高度值较小,后续的值一定大于现在放置的高度(也会存在等于的特殊情况后续单独考虑)
放置位置左侧book数值不会受影响,右侧位置的前面比我高的个数会减一(注意book[i]=j代表在下标j位置,比我高的个数有i个)
这种更新可以通过book[i]=book[i+1]实现
也就是book[4]=book[5]=5 ,在下标5比他高的个数有4个
在这里插入图片描述
更新book值
在这里插入图片描述在这里插入图片描述
这里发现有些不同是由于,前面更新book值是考虑都大于当前值,但实际上个头相等也会被记为比我高,所以单独考虑,before=2,但由于之前有一个高位5的出现了,那么我只需要找before=1即可,在具体实现的时候需要有一个sum变量记录一下之前出现过多少个跟我一样高的,before=before - sum

之所以属于贪心的题目,应该是先处理最矮的,多个最矮的,先处理前面比它高最少的

实现代码

bool cmp(const vector<int> &a,const vector<int> &b){
    
    
    if(a[0]!=b[0]) return a[0]<b[0];
    else return a[1]<b[1];
}

class Solution {
    
    
public:
    int find(vector<int>book,int v){
    
    
        if(book[v]==v) return v;
        else return find(book,book[v]);
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
    
    
        int n=people.size();
        if(n<2) return people;
        vector<vector<int>> re(n);
        vector<int>book(n,0);
        int sum=0;
        for(int i=0;i<n;i++){
    
    
            book[i]=i;
        }
        sort(people.begin(),people.end(),cmp);
        int b=people[0][0];
        for(int i=0;i<n;i++){
    
    
            int before=people[i][1];
            if(i&&b==people[i][0]){
    
    
                sum++;
                before=before-sum;
            }
            else sum=0;
            int index=book[before];
            re[index]=people[i];
            for(int i=before;i<n-1;i++){
    
    
                book[i]=book[i+1];//find(book,book[i+1]);
            }
            b=people[i][0];
        }
        return re;
    }
};

提交结果及分析

在这里插入图片描述
时间复杂度O(n)

方法二

实现思路

先放置高的位置,后续矮的人随意插入都不会影响高的结果
一、 将所有人按照身高降序排列,相同身高的情况按照K值升序排列
二、 遍历数组进行插入

people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
排序之后为[[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]]
按照此思想一次插入:
[[7,0]]
[[7,0],[7,1]]
[[7,0],[6,1],[7,1]]
[[5,0],[7,0],[6,1],[7,1]]
[[5,0],[7,0],[5,2],[6,1],[7,1]]
[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

实现代码

bool cmp(const vector<int> &a,const vector<int> &b){
    
    
    return a[0]>b[0]||a[0]==b[0]&&a[1]<b[1];
}
class Solution {
    
    
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
    
    
        int n=people.size();
        if(n<2) return people;
        vector<vector<int>> res;
        sort(people.begin(),people.end(),cmp);
        for(auto p:people) res.insert(res.begin()+p[1],p);
        return res;
    }
};

提交结果及分析

在这里插入图片描述
时间复杂度O(n)

猜你喜欢

转载自blog.csdn.net/weixin_44944046/article/details/113797209