406 java_406.根据身高重建队列

文章目录

一,406.根据身高重建队列

二, 解题思路分析

1, 大致情况分为两种分别

2, 身高相同的情况

3, 身高不同的情况

4, 在这里面有一个非常关键概念就是:当前要插入身高数小的数已经插入进入了, 而比它大身高数没有插入进入呢!!! , 所以在当前这个数前面有几个数就空出几个位置,放比他的身高数大数

三,解题代码

**C**

四, 总结

一,406.根据身高重建队列

假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对 (h, k) 表示,其中 h 是这个人的身高,k 是应该排在这个人前面且身高大于或等于 h 的人数。 例如:[5,2] 表示前面应该有 2 个身高大于等于 5 的人,而 [5,0] 表示前面不应该存在身高大于等于 5 的人。

编写一个算法,根据每个人的身高 h 重建这个队列,使之满足每个整数对 (h, k) 中对人数 k 的要求。

示例:

输入:[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

输出:[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

提示:

总人数少于 1100 人。

通过次数69,646提交次数97,421

二, 解题思路分析

1, 大致情况分为两种分别

身高相同的

身高不同的

下面我们就分析身高分析

2, 身高相同的情况

身高相同的,前面人数越多(k)是一定在后面的

例如:

( 4 , 3 ) ( 4 , 0 ) ( 4 , 2 ) ( 4 , 1 ) (4, 3)(4, 0)(4, 2)(4, 1)(4,3)(4,0)(4,2)(4,1)

( 4.0 ) 和 ( 4 , 1 ) 坐 标 中 ( 4 , 1 ) 一 定 是 在 ( 4 , 0 ) 后 面 的 (4.0)和(4, 1)坐标 中(4, 1)一定是在(4, 0)后面的(4.0)和(4,1)坐标中(4,1)一定是在(4,0)后面的

3, 身高不同的情况

这个时候我们需要单独拿出一些数据来分析:

( 2 , 0 ) , ( 4 , 0 ) , ( 5 , 0 ) , ( 3 , 1 ) (2, 0), (4,0),(5,0),(3, 1)(2,0),(4,0),(5,0),(3,1)

我们可以这样不同的身高按照身高从小到大的排序

得到( 2 , 0 ) , ( 3 , 1 ) , ( 4 , 0 ) , ( 5 , 0 ) (2, 0),(3, 1), (4,0),(5,0)(2,0),(3,1),(4,0),(5,0)

如果是一个4的数组中 都没有使用,那么在第一个放( 2 , 0 ) (2, 0)(2,0),到放( 3 , 1 ) (3, 1)(3,1)时 我检查前面是否为空如果是空记一个当到2个空再插入(3,1)数据 , 说明在( 3 , 1 ) (3,1)(3,1)前面有一个大身高3的人,所以需要跳一个1位置,所以到( 4 , 0 ) (4,0)(4,0)主要有一个空位置可以插入进入了,( 5 , 0 ) (5,0)(5,0)也是这样的处理的

4, 在这里面有一个非常关键概念就是:当前要插入身高数小的数已经插入进入了, 而比它大身高数没有插入进入呢!!! , 所以在当前这个数前面有几个数就空出几个位置,放比他的身高数大数

三,解题代码

C

int pratition(int **people, int start, int end)

{

int value = people[start][0];

int right = start;

int left = end+1;

while (1)

{

//找到最大的数的下标

while ( people[++right][0] == value? people[right][1] > people[start][1] : people[start][0] > people[right][0] )

{

if(right == end)

{

break;

}

}

//最小的值

while ( people[--left][0] == value? people[left][1] < people[start][1] : people[start][0] < people[left][0] /*people[--left][1] < value*/)

{

if (left == start)

{

break;

}

}

if (left <= right)

{

break;

}

int * temp= people[right];

people[right] = people[left];

people[left] = temp;

}

int* temp = people[start];

people[start] = people[left];

people[left] = temp;

return left;

}

void sort(int **people, int start, int end)

{

if (end <= start)

{

return;

}

int p = pratition(people, start, end);

sort(people, start, p-1);

sort(people, p+1, end);

}

/**

*快速排序

*/

void quick_sort(int **people, int size)

{

if (people == NULL || size <= 0)

{

return;

}

sort(people, 0, size-1);

}

/**

* 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 comp(const void * ptr1, const void * ptr2)

{

const int * value1 = *(const int **)ptr1;

const int * value2 = *(const int **)ptr2;

//a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]

return (value1[0] == value2[0]) ? value2[1] - value1[1] : value1[0] - value2[0];

}

int** reconstructQueue(int** people, int peopleSize, int* peopleColSize, int* returnSize, int** returnColumnSizes)

{

*returnSize = 0;

// [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]

//1. 快速排序 [[5,2],[5,0],[6,1],[7,0],[4,4],[7,1]]

quick_sort(people, peopleSize);

// 2. [[4,4],[5,2],[5,0],[6,1],[7,1],[7,0]]

// qsort(people, peopleSize, sizeof(int *), comp );

// *returnSize = peopleSize;

// *returnColumnSizes = peopleColSize;

// return people;

int **arrays = malloc(sizeof(int *) * peopleSize);

*returnColumnSizes = malloc(sizeof(int) * peopleSize);

memset(*returnColumnSizes, 0, sizeof(int)*peopleSize);

for (int i = 0; i < peopleSize; ++i)

{

int split = people[i][1] +1;

for (int j = 0; j < peopleSize; ++j)

{

if ((*returnColumnSizes)[j] == 0)

{

--split;

if (!split)

{

(*returnColumnSizes)[j] = 2;

arrays[j] = malloc(sizeof(int) * 2);

arrays[j][0] = people[i][0];

arrays[j][1] = people[i][1];

break;

}

}

}

}

*returnSize = peopleSize;

return arrays;

}

四, 总结

总结:当前要插入身高数小的数已经插入进入了, 而比它大身高数没有插入进入呢!!! , 所以在当前这个数前面有几个数就空出几个位置,放比他的身高数大数

源码地址:https://github.com/chensongpoixs/cleet_code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值