一、题目(就像是绕口令,根本看不懂)
You are given an array of people, people, which are the attributes of some people in a queue (not necessarily in order). Each people[i] = [hi, ki] represents the ith person of height hi with exactly ki other people in front who have a height greater than or equal to hi.
Reconstruct and return the queue that is represented by the input array people. The returned queue should be formatted as an array queue, where queue[j] = [hj, kj] is the attributes of the jth person in the queue (queue[0] is the person at the front of the queue).
给定一个数组[[ h,k],[ ,],[ ,]],存储***身高h***和***高于等于当前身高的人数k***。
要求:
在不改变h,k数组对的前提下排好顺序
示例:
Input: people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
Output: [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
二、思路
- 根据要求中所述的首先按身高从高到低排序:***[[7, ], [7, ], [6, ], [5, ], [5, ], [4, ]]*** (从高到低排是因为 ‘1索引’ 指的是高于等于当前的人,从高到低排才可以直接得出 ’索引1‘ )
- 为了让 ’索引1‘ 与实际匹配,先在此前基础上将 ’索引1‘ 按升序排列***[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]]*** 这样排序,k值大的在后面可以减少插入次数的同时还能保证正确性。举个例子,在身高一样,k不一样的时候,譬如[5,2]和[5,3], 对于最后排完的数组,[5,2]必然在[5,3]的前面。所以如果遍历的时候[5,3]在前面,等它先插入完,这个时候它前面会有3个大于等于它的数组对,遍历到[5,2]的时候,它必然又会插入[5,3]前面(因为它会插入链表索引为2的地方),这个时候[5,3]前面就会有4个大于等于它的数组对了,这样就会出错。
- 按照k为下标重新插入队列,按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。得到结果 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
- 实现第三步的方法:如果索引在正确位置直接插入append,否则按数组中的第二元素所示位置插入。
三、代码(理解思路的话很简单)
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
people = sorted(people, key=lambda x:(-x[0],x[1]))
queue = []
for i in people:
if i[1]==len(queue):
queue.append(i)
else:
queue.insert(i[1],i)
return queue
四、补充
贪心算法(greedy algorithm)
该题应用该算法思路
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性
时间复杂度O(nlogn + n^2) --> O(n^2)
空间复杂度O(logn)