根据身高重建队列

力扣题目链接(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. Win10 查看无线局域网的密码

    1. 打开命令行 输入 control 打开控制面板 2. 进入网络和共享中心 3. 打开连接 4. 使用如下进行查看.

  2. 01显示转换隐私转换 有8个值转为false 显示转换Number的注意点

    prompt()函数会弹出一个框,接受用户的输入.但是在实际的开发中.这样的操作是很少. 至少在我做开发的过程中没有使用过.我二没有看见人家在过开发的使用使用. console.log(Number( ...

  3. ABP-VNext 用户权限管理系统实战03---动态api调用并传递token

    一.使用动态api的目的 ABP可以自动创建C# API 客户端代理来调用远程HTTP服务(REST APIS).通过这种方式,你不需要通过 HttpClient 或者其他低级的HTTP功能调用远程服 ...

  4. 加快ios的出包速度

    在导出ipa时,通过这几种方法,可以更快地导出ipa来进行测试 不勾选bitcode 在导出ipa时,不勾选bitcode,这样会加快出包的速度,但导出来的ipa会大一些,关于bitcode可查看:& ...

  5. Python 实现SynFlood洪水攻击

    Syn-Flood攻击属于TCP攻击,Flood类攻击中最常见,危害最大的是Syn-Flood攻击,也是历史最悠久的攻击之一,该攻击属于半开放攻击,攻击实现原理就是通过发送大量半连接状态的数据包,从而 ...

  6. 【奶奶看了都会】2分钟学会制作最近特火的ikun幻术图

    1.效果展示 最近ikun幻术图特别火啊,在网上能找到各种各样的ikun姿势图片,这些图片都是AI绘制的,能和风景完美融合在一起,今天小卷就来教大家怎么做这种图片 先看看图片效果 B站视频链接: 仿佛 ...

  7. P1405 苦恼的小明 题解

    题目传送门 前置知识 扩展欧拉定理 解法 本题幂塔是有限层的,这里与 luogu P4139 上帝与集合的正确用法 中的无限层幂塔不同,故需要在到达递归边界 \(n+1\) 时进行特殊处理,对于处理 ...

  8. JS 判断对象属性是否存在,判断是否包含某个属性,是否为自身属性

    壹 ❀ 引 看过博主JS 疫情宅在家,学习不能停,七千字长文助你彻底弄懂原型与原型链这篇文章的同学应该知道,文中有专门介绍这个问题.那么为什么我要另起一篇再说一次呢?原因有两个,一是介绍原型与原型链的 ...

  9. 扯淡的DevOps,我们开发根本不想做运维!

    引言 最初考虑引用" DevOps 已死,平台工程才是未来"作为标题,但这样的表达可能太过于绝对.最终,决定用了"扯淡的"这个词来描述 DevOps,但这并不是 ...

  10. NC24961 Hotel

    题目链接 题目 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...