https://leetcode-cn.com/problems/queue-reconstruction-by-height/

难度:中等


  假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(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]]


解法1:排序+调整

  通过观察,我们可以知道,对于一组数据,如示例中的 (7,0)(7,1),无论它们所处的位置在哪,在最终结果中,它们的相对位置是不会发生变化的:(7,1) 一定会在 (7,0) 的后面,可能中间隔了一个、可能隔了 n 个。

  因此,我们可以先对这组数据排序,先保证它们的相对位置,具体做法是根据 (h, k) 来排序:我们先按 h 从大到小进行排序,这样保证了对于每一个数 i,它前面的数字都不会小于自身,然后对于 h 相同的数字,按 k 从小到大排序,这样,对于 h 相同的数据,它们的相对位置开始就是正确的。

  之后,遍历这组排序过的数据,我们使用 tuple 来表示一个 (h, k) 对,遍历过程中,数组索引 i 能够表示不小于当前 tuple 的所有 tuple 的个数(因为我们提前按 h 进行排序了),这样,我们只要根据每个 tuplek 来进行调整即可。

  具体调整方法是:对于当前的 tuple ,若 k < i ,说明在当前 tuple 前面的位置,比它高的 tuple 个数太多了,需要将这个 tuple 向前调整 i-k 个位置,让其前面的 tuple 个数刚好等于 k,也就是移动到第 k 个位置。且这样调整并不会影响到已调整的序列,因为那些数据的相对位置并不会发生改变。

JS 代码:

/*** @param {number[][]} people* @return {number[][]}*/
var reconstructQueue = function(people) {if (people.length < 2) {return people;}let res = [];// 先根据 h 和 k 排序,主 h 副 k , h 从大到小排序,k 从小到大排序people.sort((a, b) => {if (a[0] === b[0]) {return a[1] - b[1];}return b[0] - a[0];});for (let i = 0; i < people.length; i++) {let k = people[i][1];if (k < i) {res.splice(k, 0, people[i]);} else {res[i] = people[i];}}return res;
};

解法2:逐个插入、调整

(第 27/37 个 case 会超时)

  主要思路是先找到序列的第一个 tuple ,然后根据每个 tuplehk 找到插入的位置,所有数据都插入完成之后,有些 tuple 会因为插入操作而导致站位错误,因此需要逐个检查判断是否站错,若站错,则将这个 tuple 重新插入,反复执行此操作,直到所有数据都满足站位要求:

/*** @param {number[][]} people* @return {number[][]}*/
var reconstructQueue = function(people) {if (people.length < 2) {return people;}let res = [];let n = people.length;let first;let tuple, k, height, insertIndex;// 先进行第一次排序for (let i = 0; i < n; i++) {tuple = people[i];k = tuple[1];height = tuple[0];insertIndex = 0;if (k === 0) {while(insertIndex < res.length && res[insertIndex][0] < height) {insertIndex++;}res.splice(insertIndex, 0, tuple);} else {while(insertIndex < res.length && k > 0) {if (res[insertIndex++][0] >= height) {k--;}}res.splice(insertIndex, 0, tuple);}}let flag = true;while(flag) {flag = false;for (let i = 0; i < n; i++) {tuple = res[i];k = tuple[1];height = tuple[0];if (k !== 0) {// 遍历当前 tuple 前面的人,看是否满足 k 的要求for (let j = 0; j < i; j++) {let tuple1 = res[j];if (tuple1[0] >= height) {k--;}}if (k !== 0) {k = tuple[1]; // k 要重新赋值,用于下面的重新插入res.splice(i, 1); // 将错误的 tuple 从结果中移除flag = true; // 需要再次判断break;}}}// 若存在错误的站位,则重新插入,且 k 、height 和 tuple 可以就使用之前的if (flag) {insertIndex = 0;while(insertIndex < n-1 && k > 0) {if (res[insertIndex++][0] >= height) {k--;}}res.splice(insertIndex, 0, tuple);}}return res;
};

LeetCode 406. 根据身高重建队列相关推荐

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

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

  2. LeetCode 406. 根据身高重建队列(排序)

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

  3. leetcode 406. 根据身高重建队列(贪心算法)

    假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对 (h, k) 表示,其中 h 是这个人的身高,k 是应该排在这个人前面且身高大于或等于 h 的人数. 例如:[5,2] 表示前面应该有 2 个 ...

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

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

  5. 2022-3-21 Leetcode 406.根据身高重建队列

    先给数组排序,第一个数较大的在前面,如果第一个数字相同,第二个数字比较小的在前面. 之后再通过插入调整顺序,从头开始,按照第二个数字插入. 为什么这样做是正确的? 因为第二个数字是新插入的人的前面有几 ...

  6. 171. Leetcode 406. 根据身高重建队列 (贪心算法-两个维度权衡题目)

    class Solution:def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:people.sort ...

  7. 力扣Leetcode之Java解题406根据身高重建队列

    406. 根据身高重建队列 题目: 假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序).每个 people[i] = [hi, ki] 表示第 i 个人的身 ...

  8. 贪心算法|406. 根据身高重建队列|先排序后插队

    贪心算法|406. 根据身高重建队列|先排序后插队 406. 根据身高重建队列 - 力扣(LeetCode) (leetcode-cn.com) 题目 假设有打乱顺序的一群人站成一个队列,数组 peo ...

  9. 406. 根据身高重建队列

    链接:406. 根据身高重建队列 题解: class Solution {public:vector<vector<int>> reconstructQueue(vector& ...

最新文章

  1. 史上首次,强化学习算法控制核聚变登上Nature:DeepMind让人造太阳向前一大步...
  2. java中jtextfield_java中的JTextField
  3. selenium中的对文本进行全选,复制,粘贴,剪切和删除的操作
  4. Vagrant挂载目录失败mount: unknown filesystem type ‘vboxsf’
  5. TeamCola - 最好用的团队工作日志软件
  6. 华三ospf联动bfd_HCIE2020__路由交换专家__BFD综合实验
  7. 高等代数第3版下 [丘维声 著] 2015年版_书籍推荐 | 关于数学分析和高等代数
  8. SPSS基本数据处理(二)
  9. 自动驾驶商用车需要什么样的电气架构?
  10. 有限元分析基本理论问答
  11. 费用型采购订单后台配置
  12. css交集选择器的使用
  13. WEB--3D立体魔方小游戏 (附源码)
  14. C\C ++语言 文件备份实验
  15. 用js函数判断一个数是否为素数
  16. linux常用命令2
  17. 单边指数信号的傅立叶matlab,实验四连续信号的傅立叶变换
  18. 玄学资料库(一)NPM、PYPI、DockerHub 备份
  19. amd 邮件 服务器,[转]免费邮件服务器hMailServer搭配SpamAssassin过滤垃圾邮件:安装和设置...
  20. CAPEX/OPEX概念解释

热门文章

  1. 聊聊底线 | 坏数据与假数据
  2. 8种常被忽视的SQL错误用法,快来认领一下!
  3. 再有人问你MySQL是如何查询数据的,请把这篇文章甩给他!
  4. 某程序员吐槽自己追求某字节HR,暧昧半年,见面后却被告知是普通朋友!心态已崩!网友:别追HR!道行太深!...
  5. 突破高连接性能瓶颈,图数据库在银行业这么用
  6. 如何快速融入团队(六)
  7. Docker是世界上最牛逼的CaaS!
  8. 如何设计出优秀的Restful API?
  9. 敏捷开发中如何做质量管理?
  10. 企业如何告别这 5 类不靠谱的员工?