题目描述
假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。
请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。
示例
示例 1:
输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解释:
编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。
示例 2:
输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/qu…
实现
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
// 贪心算法:按照身高从高到低进行排序,矮的放后面,因为矮的即使放在了高的前面,也不会对之前高的产生影响;但高的放在前面,对矮的结果就会产生影响了。
int compare(const void *a, const void *b)
{
int *pa = *(int**)a;
int *pb = *(int**)b;
return pa[0] == pb[0] ? pa[1] - pb[1] : pb[0] - pa[0]; // 如果相等,按照个数升序排列,否则按照身高降序排列
}
int **reconstructQueue(int **people, int peopleSize, int *peopleColSize, int *returnSize, int **returnColumnSizes)
{
if (people == NULL || peopleSize == 0 || peopleColSize == NULL) {
*returnSize = 0;
return NULL;
}
int **res = (int**)malloc(sizeof(int*) * peopleSize);
*returnSize = 0;
*returnColumnSizes = (int*)malloc(sizeof(int) * peopleSize);
for (int i = 0; i < peopleSize; i++) {
(*returnColumnSizes)[i] = 2;
}
qsort(people, peopleSize, sizeof(int*), compare);
/*
* 插入过程
* [[7, 0]]
* [[7, 0], [7, 1]]
* [[7, 0], [6, 1], [7, 1]] 将 [6, 1] 插入到 i = 1 处,之前在这的元素会后移。
* [[5, 0], [7, 0], [6, 1], [7, 1]]
* [[5, 0], [7, 0], [5, 2], [6, 1], [7, 1]]
* [[5, 0], [7, 0], [5, 2], [6, 1], [4, 4], [7, 1]]
*/
for (int i = 0; i < peopleSize; i++) {
int *person = people[i];
(*returnSize)++;
// 插入位置之后的往后移动
for (int j = (*returnSize) - 1; j > person[1]; j--) {
res[j] = res[j-1];
}
// 插入本次值
int *tmp = (int*)malloc(sizeof(int) * 2);
tmp[0] = person[0];
tmp[1] = person[1];
res[person[1]] = tmp;
}
return res;
}