题目
假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(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]]
来源:力扣(LeetCode)
链接:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
个子高的人看不到前面比自己矮的人,所以先按照身高降序,这样再把矮个子放到高个子前面,不影响高个子的前面有多少个比他高(或相等)的人数。
1.对people按照身高降序排序,身高相同,则按k升序排序
2.创建ans切片保存结果,ans[0] = people[0]
3.从people[1]开始遍历,将people[i]放到ans中people[i][1]的位置,即放到相应的k。如果该位置已经有元素,则从该元素开始往后移动一位,然后把people[i]插入
(这样做仍然能保持满足条件,是因为按照身高降序,插入的新元素的身高比原位置的元素要小(或相等,又由于身高相等时,按照k升序排序,所以也满足))
代码
func reconstructQueue(people [][]int) [][]int {
// 特殊情况
if len(people) == 0 || len(people) == 1 {
return people
}
// 按照身高降序排序,身高相同,则按k升序排序
sort.Slice(people, func(i, j int) bool {
if people[i][0] == people[j][0] {
return people[i][1] < people[j][1]
}
return people[i][0] > people[j][0]
})
ans := make([][]int, len(people))
for i := 0; i < len(people); i++ {
ans[i] = make([]int, 2)
}
// 从people[1]开始插入到k位置,如果该位置已经有元素,则该位置到i-1都后移一位,再插入
ans[0] = people[0]
for i := 1; i < len(people); i++ {
t := people[i][1]
for j := i; j > t; j-- {
ans[j] = ans[j-1]
}
ans[t] = people[i]
}
return ans
}
复杂度分析
时间复杂度:O(N2)
空间复杂度:O(N)
执行结果
执行用时 :16 ms, 在所有 Go 提交中击败了90.82% 的用户
内存消耗 :5.9 MB, 在所有 Go 提交中击败了90.91%的用户