题目详情

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

注意:

总人数少于1100人。

示例

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

解题思路

此题放在贪心算法中, 是用贪心的思想来解题

首先对数组 按照第一个元素height 降序排列

此时 数组前面的元素的height 大于后面元素的height

然后 以每个元素的k值 插入到返回数组里, 比如元素的k为 2, 就插到 返回数组的下标为2的位置。

以题目的例子来进行操作

这是原来的数组
people = [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] 按照height进行降序排序之后
people = [[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]] 对降序后的people数组 从第一个元素开始 把每个元素加入到返回数组
加入的策略是, 按照每个元素的k 来插入到下表为k的位置上 1.
插入 [7,0]
插入到离开始位置偏移了0个距离的位置。
result = [[7,0]]
2.
插入 [7,1]
插入到离开始位置偏移了1个距离的位置,即插入到[7,0]的后面。
result = [[7,0], [7,1]]
3.
插入 [6,1]
插入到离开始位置偏移了1个距离的位置,即插入到[7,0]的后面。
result = [[7,0], [6,1], [7,1]]
4.
插入 [5,0]
插入到离开始位置偏移了0个距离的位置,即插入到[7,0]的前面。
result = [[5,0], [7,0], [6,1], [7,1]]
5.
插入 [5,2]
插入到离开始位置偏移了2个距离的位置,即插入到[7,0]的后面。
result = [[5,0], [7,0], [5,2], [6,1], [7,1]]
6.
插入 [4,4]
插入到离开始位置偏移了4个距离的位置,即插入到[6,1]的后面。
result = [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] 得到最终结果
result: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

贪心证明

把每个元素以k 插进去, 因为是按照height 来由大到小插进去的, 把元素插进第k位置, 插入后前面的height 是比当前插入元素大(因为已经插入的元素height大或者相等), 这就满足了排在前面身高大于或等于的人数为k, 但是要注意 我现在说的数组 并不是最终结果的数组, 而是插入这个元素形成的中间数组。 是相对于 中间数组来说的。

那么有一个问题了, 最终结果里 [6,1] 前面有[5,0], [5,1], 这些height是小于6的, 但是排在[6,1]前面, 这些元素是在[6,1]加进去之后加进去的, 这些加进去的元素对 [6,1] 满足的条件(排在前面身高大于或等于的人数为k) 会有影响吗? 答案是不会的,因为在[6,1]加进去的元素的height 是小于6的 无论加在哪个地方对 [6,1]的 k 不会改变。

综上, 此算法能求出结果

AC代码

class Solution {
public:
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
vector<pair<int, int>> result; // lambda 表达式
sort(people.begin(), people.end(), [](pair<int, int> a, pair<int, int> b){
return a.first > b.first || (a.first == b.first && a.second < b.second);
}); for (auto i: people) {
result.insert(result.begin() + i.second, i);
}
return result;
}
};

总结

因为在前面贪心的过程中 插入的元素不会对前面已经插入元素的k造成印象, 所以才能贪心, 否则 就可能用到其他的方法来解题了。

最新文章

  1. java 枚举的简单应用。
  2. Appium运行时,error: Logcat capture failed: spawn ENOENT的解决办法
  3. C/C++程序终止时执行的函数——atexit()函数详解
  4. android AlarmManager 详解
  5. WINCE+6410 拨号上网
  6. 表与表 不同条件下的关联SQL
  7. xml学习篇(二) ----JSON 和XML对比
  8. sql语句:union
  9. cf Ping-Pong (Easy Version)
  10. java 实现排序
  11. 物联网 开发板 基于ESP8266
  12. 河南多校大一训练赛 E 开餐馆
  13. 面向对象的三大特征——封装、继承、多态(&amp;常用关键字)
  14. 阻止浏览器冒泡事件,兼容firefox和ie
  15. 基于tcp实现远程执行命令
  16. webpack-dev-server的执行逻辑
  17. REST easy with kbmMW #3 – SSL
  18. 一个简单RPC框架是怎样炼成的(IV)——实现RPC消息的编解码
  19. swift - 表格的编辑功能(添加、删除)
  20. 请写出用于校验HTML文本框中输入的内容全部为数字的javascript代码

热门文章

  1. Python Hacking Tools - Vulnerability Scanner
  2. kubernetes系列(十七) - 通过helm安装dashboard详细教程
  3. C++语法小记---面向对象模型(实例的内存分布)
  4. 搞定 CompletableFuture,并发异步编程和编写串行程序还有什么区别?你们要的多图长文
  5. 面试题四十:数组中最小的k个数
  6. Ansible基础
  7. 想学Python不知道从哪里开始学?|百度网盘免费下载| 这本入门书了解下
  8. 二手99新iPhone8Plus有锁移动联通版
  9. 那些年拿过的shell之springboot jolokia rce
  10. 第七章 vuex专题