【Leetcode笔记】406.根据身高重建队列

1. 题目要求

在这里插入图片描述

2.解题思路

首先,按照每个人的身高属性(即people[i][0])来排队,顺序是从大到小降序排列,如果遇到同身高的,按照另一个属性(即people[i][1])来从小到大升序排列。
使用到C++的sort()函数,第三个参数cmp函数自己定义:

static bool cmp(const vector<int>& a, const vector<int>& b)
{
// 使用const关键字来确保在函数内部不会修改a和b
	if(a[0] == b[0]) return a[1] < b[1]; // 象形的记,升序
	return a[0] > b[0];
}

接下来再次遍历people数组,从前到后将每个元素放入到一个二维数组里。
为什么从前到后?
先排身高更高的,后面身高矮的即使因为第二个属性需要插入到前面人的中间去也没关系,反正身高更高的第二个属性不受影响。但是从后到前先排身高矮的可就不行了。

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;
    }

时间复杂度要大于O(nlogn + n ^ 2),首先C++里的sort函数的时间复杂度就是O(nlogn),这个排序函数内部并不是单一的快速排序或者是其他的,而是动态改变的,可能一开始数据量较大时先快速排序对半分,等分到后面则使用插入排序;C++的vector是一个动态数组,插入操作是先考虑原来的数组大小够不够,如果不够那就二倍扩容,然后把原数组拷贝到新数组再插入新的元素,所以时间复杂度要大于O(n^2)。
将数组改成链表

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());

注意

sort函数的第三个参数是cmp,cmp是一个比较函数,想这样使用 sort (people.begin(), people.end(), cmp);那必须得将cmp声明为静态成员函数,这样就不需要将函数实例化了。

3.ACM模式代码

#include <vector>
#include <algorithm>
#include <list>
#include <iostream> // 用于输出调试

using namespace std;

class Solution {
public:
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        // Sort by height descending, and if heights are same, by k ascending
        if (a[0] == b[0]) {
            return a[1] < b[1]; // Sort by k in ascending order
        } else {
            return a[0] > b[0]; // Sort by height in descending order
        }
    }
    
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        // Sort people array using custom comparator
        sort(people.begin(), people.end(), cmp);
        
        // Use list for efficient insertion
        list<vector<int>> que;
        
        // Insert into list at the specified index (k value)
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1]; // k value tells us the exact index to insert
            auto it = que.begin();
            advance(it, position); // Move iterator to the correct position
            que.insert(it, people[i]); // Insert person into the list
        }
        
        // Convert list back to vector for returning the result
        return vector<vector<int>>(que.begin(), que.end());
    }
};

int main() {
    Solution sol;
    
    // Example usage:
    vector<vector<int>> people = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}};
    vector<vector<int>> result = sol.reconstructQueue(people);
    
    // Print the result
    cout << "[";
    for (const auto& person : result) {
        cout << "[" << person[0] << ", " << person[1] << "],";
    }
    cout << "]";
    cout << endl;
    
    return 0;
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值