力扣 406. 根据身高重建队列

题目来源:https://leetcode.cn/problems/queue-reconstruction-by-height/description/

C++题解1:分别对h和k两个维度进行考虑,我这里是优先考虑k值,k值相同的时候h小的排前面。然后再一一遍历,对于people[i],找到比people[i][0]大的位置,准备插入people[j+1][0],但是插入前还需判断一下插入位置people[j+1][0]是否大于people[i][0],不是的话就继续往后寻找插入位置。

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        if(a[1] < b[1]) return true;
        else if(a[1] == b[1]) {
            if(a[0] < b[0]) return true;
        }
        return false;
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), cmp);
        int len = people.size();
        for(int i = 0; i < len; i++) {
            int count = people[i][1];
            for(int j = 0; j <= i; j++) {
                if(people[j][0] >= people[i][0]) count--;
                if(count == 0) {
                    if(j+1!=i && people[j+1][0] >= people[i][0]){  // 插入
                        people.insert(people.begin()+j+1, people[i]);
                        people.erase(people.begin()+i+1);
                        break;  // 找到插入的位置就跳出循环
                    } 
                }
            }
        }
        return people;
    }
};

C++题解2(来源代码随想录):优先身高排序,从大到小排(身高相同的话则k小的站前面),让高个子在前面。此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高! 后面只需要按照k为下标重新插入队列就可以了。采用vector实现。

cpp 复制代码
class Solution {
public:
    static bool cmp(const vector<int>& a, const 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) {
        sort (people.begin(), people.end(), cmp);
        vector<vector<int>> que;
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1];
            que.insert(que.begin() + position, people[i]);
        }
        return que;
    }
};

C++题解3(来源代码随想录):使用vector是非常费时的,C++中vector(可以理解是一个动态数组,底层是普通数组实现的)如果插入元素大于预先普通数组大小,vector底部会有一个扩容的操作,即申请两倍于原先普通数组的大小,然后把数据拷贝到另一个更大的数组上。所以使用vector(动态数组)来insert,是费时的,插入再拷贝的话,单纯一个插入的操作就是O(n^2)了,甚至可能拷贝好几次,就不止O(n^2)了。

vector的大小有两个维度一个是size一个是capicity,size就是我们平时用来遍历vector时候用的,而capicity是vector底层数组(就是普通数组)的大小,capicity可不一定就是size。当insert数据的时候,如果已经大于capicity,capicity会成倍扩容,但对外暴漏的size其实仅仅是+1。扩容时重新申请一个二倍于原数组大小的数组,然后把数据都拷贝过去,并释放原数组内存。

list底层是链表实现,插入效率比vector高的多。

cpp 复制代码
class Solution {
public:
    // 身高从大到小排(身高相同k小的站前面)
    static bool cmp(const vector<int>& a, const 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) {
        sort (people.begin(), people.end(), cmp);
        list<vector<int>> que; // list底层是链表实现,插入效率比vector高的多
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1]; // 插入到下标为position的位置
            std::list<vector<int>>::iterator it = que.begin();
            while (position--) { // 寻找在插入位置
                it++;
            }
            que.insert(it, people[i]);
        }
        return vector<vector<int>>(que.begin(), que.end());
    }
};
相关推荐
式5161 小时前
线性代数(七)主变量与特解
线性代数·算法
业精于勤的牙7 小时前
浅谈:算法中的斐波那契数(二)
算法·职场和发展
不穿格子的程序员8 小时前
从零开始写算法——链表篇4:删除链表的倒数第 N 个结点 + 两两交换链表中的节点
数据结构·算法·链表
liuyao_xianhui8 小时前
寻找峰值--优选算法(二分查找法)
算法
dragoooon348 小时前
[hot100 NO.19~24]
数据结构·算法
神仙别闹8 小时前
基于QT(C++)实现学本科教务系统(URP系统)
数据库·c++·qt
deng-c-f9 小时前
Linux C/C++ 学习日记(49):线程池
c++·学习·线程池
ulias2129 小时前
C++ 的容器适配器——从stack/queue看
开发语言·c++
daidaidaiyu9 小时前
FFmpeg 关键的结构体
c++·ffmpeg
Tony_yitao9 小时前
15.华为OD机考 - 执行任务赚积分
数据结构·算法·华为od·algorithm