406. 根据身高重建队列
难度中等442
假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(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]]
方法:贪心算法
这个问题是让我们重建队列。
让我们从最简单的情况下思考,当队列中所有人的 (h,k)
都是相同的高度 h
,只有 k
不同时,解决方案很简单:每个人在队列的索引 index = k
。
即使不是所有人都是同一高度,这个策略也是可行的。因为个子矮的人相对于个子高的人是 “看不见” 的,所以可以先安排个子高的人。
上图中我们先安排身高为 7
的人,将它放置在与 k
值相等的索引上;再安排身高为 6
的人,同样的将它放置在与 k
值相等的索引上。
该策略可以递归进行:
-
将最高的人按照
k
值升序排序,然后将它们放置到输出队列中与k
值相等的索引位置上。 -
按降序取下一个高度,同样按
k
值对该身高的人升序排序,然后逐个插入到输出队列中与k
值相等的索引位置上。 -
直到完成为止。
整体思路:
- 先按身高降序排序,相同身高按k升序排序,经过此次排序后高的人一定在矮的人的前面并且相同高度的人的相对顺序就是最终结果的相对顺序。请记住这两点,敲黑板
- 创建一个集合,这个集合的每个元素是一个一维数组,也就是我们二维数组的一行。
- 以行为单位遍历排好序的people[][]数组,假设每行数据是p[], 把每行元素插入到集合的索引为p[1]的位置,
- 把集合中的数据转换为一个二维数组,返回即是正确结果
下面解释为什么经过第三步后就达到了我们题目要求的输出结果:
经过第一步排序后高的人一定在矮的人的前面并且相同高度的人的相对顺序就是最终结果的相对顺序,所以 在进行第三步的过程中,高的人的数据肯定是先被存入集合的,所以每当我们取出一行数据,集合中已有的元素的身高肯定都是大于等于当前元素的身高的,所以当我们取出p[]数组后,发现前面应该有p[1]个人比自己高或者高度和自己相同,那么当前元素就应该排在集合的p[1]下标的位置(仔细想想是不是),好比说目前有一个队列的人,这些人要么比你高,要么和你一样高