【LeetCode贪心#08】根据身高重建队列(还是涉及处理两个维度的信息)
根据身高重建队列
假设有打乱顺序的一群人站成一个队列,数组 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)。范围构造函数允许我们使用一个迭代器范围(例如 begin 和 end)来创建一个 vector,从而将另一个容器(或者是一段数组)中的元素复制到新的 vector 中。
使用范围构造函数可以方便地将一个容器或数组中的元素快速转换为一个 vector 对象,并且不需要手动逐个插入元素。
【LeetCode贪心#08】根据身高重建队列(还是涉及处理两个维度的信息)的更多相关文章
- 【LeetCode】406-根据身高重建队列
title: 406-根据身高重建队列 date: 2019-04-15 21:13:06 categories: LeetCode tags: Java容器 比较器 贪心思想 题目描述 假设有打乱顺 ...
- 【LEETCODE】73、根据身高重建队列 第406题
说实话,这道题我没想出来,但是看解题报告题解比较让人觉得眼前一亮,这里记录下来 package y2019.Algorithm.greedy.medium; import java.util.Arra ...
- LeetCode 406. 根据身高重建队列(Queue Reconstruction by Height) 46
406. 根据身高重建队列 406. Queue Reconstruction by Height 题目描述 假设有打乱顺序的一群人站成一个队列.每个人由一个整数对 (h, k) 表示,其中 h 是这 ...
- Leetcode 406.根据身高重建队列
根据身高重建队列 假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列. 注意:总人 ...
- Java实现 LeetCode 406 根据身高重建队列
406. 根据身高重建队列 假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列. ...
- Leetcode:根据身高重建队列
题目 假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列. 注意: 总人数少于11 ...
- 406 Queue Reconstruction by Height 根据身高重建队列
假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列.注意:总人数少于1100人.示 ...
- [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 ...
- [LeetCode] Implement Stack using Queues 用队列来实现栈
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- LeetCode 232:用栈实现队列 Implement Queue using Stacks
题目: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是 ...
随机推荐
- [转帖]Linux系统awk命令详解
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 ...
- echarts饼状图自定义legend的样式付费
先看效果图 代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- vue 路由守卫是否携带token
//整个实例出来 配置路由守卫 const router = new Router({ //这里面是路由配置哈 }) router.beforeEach((to, from, next) => ...
- 【小分享】vm-storage中,计算metric的平均长度
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 表达式如下: sum by (type) (vm_cach ...
- 辣鸡 mac 下 pycharm 中代码拖拽的问题
Editor –> General Enable Drag'n'Drop functionality in Editor
- python-ssh链接linux查询日志,并按日志等级在控制台分颜色输出日志
import paramiko # unicode_utils.py def to_str(bytes_or_str): """ 把byte类型转换为str :param ...
- Laravel日期处理
1. 常用: echo Carbon::now(); // 2023-04-08 18:07:24 echo Carbon::today(); // 2023-04-08 00:00:00 echo ...
- Java 数字 默认是 Integer类型的问题,System.currentTimeMillis() + (180 * 24 * 60 * 60 * 1000)的问题,剖析、Long + Integer的问题
最终结论: (180 * 24 * 60 * 60) 这种计算表达式在 Java中是默认以 Integer类型来的,若不超过 Integer的最大值则没有问题,若超过则必须用 (180 * 24 * ...
- .NET Core开发实战(第19课:日志作用域:解决不同请求之间的日志干扰)--学习笔记
19 | 日志作用域:解决不同请求之间的日志干扰 开始之前先看一下上一节的代码 // 配置的框架 var configBuilder = new ConfigurationBuilder(); con ...
- Java-生成字符串的MD5值
方法一:public static String getMd5(String str) { MessageDigest md5 = null; try { md5 = MessageDigest.ge ...