根据身高重建队列

力扣题目链接(opens new window)

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

示例 1:

  • 输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
  • 输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
  • 解释:
    • 编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
    • 编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
    • 编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
    • 编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
    • 编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
    • 编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
    • 因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。

示例 2:

  • 输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
  • 输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

提示:

  • 1 <= people.length <= 2000
  • 0 <= hi <= 10^6
  • 0 <= ki < people.length

题目数据确保队列可以被重建

思路

乍一看题目没看懂,感觉需要考虑的要素很多

举个例子:[7,0]

意思就是当前这个人身高是7,前面有0个身高更高或者相同的人

然后题目要求我们对people数组进行排序,并满足对应要求,即上面这个[7,0]在排序后的位置必须满足:当前这个人身高是7,前面有0个身高更高或者相同的人

此时有两个元素需要考虑,即**当前的身高 h 前面有几个相同身高的人 k **

参考发糖果,涉及两个维度时,需要分别处理

以 示例1 来讲

  • 输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
  • 输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

可以先针对身高进行排序,结果如下:

[[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]

这里需要自定义sort的排序规则,详见

排序逻辑:显然,我们希望先比较身高h,如果身高相同就比较k

然后使用 k 作为下标,将数组插入到对应位置,模拟过程如下:

定义一个新数组(后续会改用链表)

  • 插入[7,0]:[[7,0]]

  • 插入[7,1]:[[7,0],[7,1]]

  • 插入[6,1]:[[7,0],[6,1],[7,1]]

    (身高为6,前面只能有1个大于等于6的,所以它可以插在当前位置,该位置也恰好是1)

  • 插入[5,0]:[[5,0],[7,0],[6,1],[7,1]](身高为5,前面只能有0个大于等于5的,只能插在最开始,即0处)

  • 插入[5,2]:[[5,0],[7,0],[5,2],[6,1],[7,1]]

  • 插入[4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

此时完成插入的数组,与 示例1 输出一致

题外话:std::list<vector>

什么时候用std::list<vector<int>>,什么时候用list<vector<int>>

std::list<vector<int>>list<vector<int>> 都是 STL 容器,只是前者在使用时需要加上 std:: 命名空间限定符,后者需要引入 using namespace std 或使用 std::list。它们的本质是相同的,都是双向链表容器,存储的元素类型都是 vector<int>

一般情况下,建议使用 list<vector<int>>,因为 std:: 命名空间限定符的使用会增加代码的可读性复杂度。但是如果你的代码中使用了 using namespace std,那么就可以使用 std::list<vector<int>>,或者在函数内使用 using std::list

需要注意的是,使用链表容器时需要注意在频繁的插入、删除操作时,链表的效率要比 vector 容器高。如果你的应用场景需要频繁进行元素的插入、删除操作,那么链表容器会更适合。但是,如果需要随机访问元素,则应使用 vector 容器。

代码

题外话:容器list

插入和删除

#include <list>

void printList(const list<int>& L) {
for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
//插入和删除
void test01(){
list<int> L;
//尾插
L.push_back(30);
//头插
L.push_front(300); printList(L);
//尾删
L.pop_back();
printList(L); //头删
L.pop_front();
printList(L); //插入
list<int>::iterator it = L.begin();
L.insert(++it, 1000);
printList(L); //删除
it = L.begin();
L.erase(++it);
printList(L); //移除
L.push_back(10000);
printList(L);
L.remove(10000);
printList(L); //清空
L.clear();
printList(L);
} int main() {
test01();
system("pause");
return 0;
}
完整代码

步骤:

1、自定义排序规则cmp

2、对people数组进行排序

3、创建一个list用于存放插入后的数组(初始化迭代器)

4、for循环遍历people数组,获取K作为位置值并保存

5、使用位置值不断修改迭代器it,找到插入位置。然后插入对应的people中的vector

class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b){
//身高从大到小排.如果身高相等,就比较前面有几个相同身高的人(身高相同k小的站前面)
if(a[0] == b[0]) return a[1] < b[1];//比较k值(从小到大)
return a[0] > b[0];//比较身高(从大到小)
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);//对people进行排序
list<vector<int>> que;//创建一个list用于存放插入后的数组
for(int i = 0; i < people.size(); ++i){
int pos = people[i][1];//获取k值作为位置值
list<vector<int>>::iterator it = que.begin();//初始化迭代器
while(pos--){//使用pos位置变量确认需要插入的位置
it++;//修改迭代器指向的位置
}
que.insert(it, people[i]);
}//因为要返回的是一个vector,所以还要以que的范围来创建一个新的vector
return vector<vector<int>>(que.begin(), que.end());
}
};
题外话:范围构造函数(Range Constructor)

上面代码中,因为题目要求返回类型是vector,所以需要将 que (STL 容器,list)中的元素转换为一个二维向量 vector<vector<int>>

具体来说,que.begin()que.end() 分别返回指向容器 que 中第一个和最后一个元素的迭代器。这个代码片段使用这两个迭代器作为参数传递给 vector 的构造函数,这样就可以创建一个新的二维向量,其中包含了容器 que 中的所有元素。每个元素都被转换为一个 vector<int>,并作为二维向量中的一行。

这种创建 vector 的方式叫做范围构造函数(Range Constructor)。范围构造函数允许我们使用一个迭代器范围(例如 beginend)来创建一个 vector,从而将另一个容器(或者是一段数组)中的元素复制到新的 vector 中。

使用范围构造函数可以方便地将一个容器或数组中的元素快速转换为一个 vector 对象,并且不需要手动逐个插入元素。

【LeetCode贪心#08】根据身高重建队列(还是涉及处理两个维度的信息)的更多相关文章

  1. 【LeetCode】406-根据身高重建队列

    title: 406-根据身高重建队列 date: 2019-04-15 21:13:06 categories: LeetCode tags: Java容器 比较器 贪心思想 题目描述 假设有打乱顺 ...

  2. 【LEETCODE】73、根据身高重建队列 第406题

    说实话,这道题我没想出来,但是看解题报告题解比较让人觉得眼前一亮,这里记录下来 package y2019.Algorithm.greedy.medium; import java.util.Arra ...

  3. LeetCode 406. 根据身高重建队列(Queue Reconstruction by Height) 46

    406. 根据身高重建队列 406. Queue Reconstruction by Height 题目描述 假设有打乱顺序的一群人站成一个队列.每个人由一个整数对 (h, k) 表示,其中 h 是这 ...

  4. Leetcode 406.根据身高重建队列

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

  5. Java实现 LeetCode 406 根据身高重建队列

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

  6. Leetcode:根据身高重建队列

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

  7. 406 Queue Reconstruction by Height 根据身高重建队列

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

  8. [Swift]LeetCode406. 根据身高重建队列 | Queue Reconstruction by Height

    Suppose you have a random list of people standing in a queue. Each person is described by a pair of ...

  9. [LeetCode] Implement Stack using Queues 用队列来实现栈

    Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...

  10. LeetCode 232:用栈实现队列 Implement Queue using Stacks

    题目: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是 ...

随机推荐

  1. 【转帖】eBay 云计算“网”事:网络超时篇

    https://www.infoq.cn/article/JmCbkA0XX9NqrcX6loIo eBay技术荟 2020-06-19 本文字数:5508 字 阅读完需:约 18 分钟 导读 eBa ...

  2. Python学习之六_同时访问Oracle和Mysql的方法

    Python学习之六_同时访问Oracle和Mysql的方法 背景 jaydebeapi 可以访问大部分数据库. 但是他有一个问题是仅能够访问一种类型的数据库. 如果同事连接两种数据库,那么就会出现问 ...

  3. [转帖]linux求数组的交集,shell/bash 交集、并集、差集

    方法一(直接用文件名):取两个文本文件的并集.交集.差集 并: sort -m 交: sort -m 差 file1 - file2: sort -m 方法二(用变量参数):取两个文本文件的并集.交集 ...

  4. 非root用户搭建sftp以及进行简要使用的介绍

    sftp的简介 关于sftp sftp是Secure FileTransferProtocol的缩写,安全文件传送协议,可以为传输文件提供一种安全的加密方法. sftp与 ftp有着几乎一样的语法和功 ...

  5. 没有虚拟DOM版本的vue(Vue Vapor)

    前言 随着Svelte和SolidJS的流行,无虚拟DOM模式逐渐开始火了起来.vue也推出了无虚拟DOM模式的版本,就是我们今天要讲的Vue Vapor. 什么是Vue Vapor Vue Vapo ...

  6. 【我在京东做研发】揭秘支撑京东万人规模技术人员协作的行云DevOps平台

    分享人:孙长虹 京东云DevOps解决方案架构师 复旦大学计算机系毕业,并拥有人民大学心理学硕士学位.曾任职于Alcatel-Lucent,IBM和惠普,具有丰富的大型复杂产品研发及项目管理经验,擅长 ...

  7. Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验

    开源应用管理平台 Walrus 0.5 已于近日正式发布! Walrus 0.4 引入了全新应用模型,极大程度减少了重复的配置工作,并为研发团队屏蔽了云原生及基础设施的复杂度.Walrus 0.5 在 ...

  8. 【CSDN浏览器插件测评超详细版】——万能便捷的C功能,直接爱不释手,强烈推荐!更多功能等你探索

    我的界面预览: 1.下载安装 下载链接:https://plugin.csdn.net/?utm_source=chajian-contest-1210#/chrome-index-help 说明:若 ...

  9. C/C++ Qt 常用数据结构

    Qt 是一个跨平台的图形化类库,常用数据结构就是对C++ STL的二次封装,使其更加易用,如下是经常会用到的一些数据结构和算法,其中包括了QString,QList,QLinkedList,QVect ...

  10. DAPR-分布式系统运行时简介

    Dapr全称Distributed Application Runtime,翻译过来就是分布式应用程序运行时,在v1.0发布后得到了极大的发展.本章将向你介绍Dapr架构的核心概念,为您使用Dapr进 ...