406. 根据身高重建队列

198 阅读2分钟

题目描述

假设有打乱顺序的一群人站成一个队列,数组 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;
}