地址:
力扣https://leetcode-cn.com/problems/boats-to-save-people/
题目:
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3 输出:1 解释:1 艘船载 (1, 2) |
示例 2:
输入:people = [3,2,2,1], limit = 3 输出:3 解释:3 艘船分别载 (1, 2), (2) 和 (3) |
示例 3:
输入:people = [3,5,3,4], limit = 5 输出:4 解释:4 艘船分别载 (3), (3), (4), (5) |
提示:
1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000 |
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/boats-to-save-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
如果在一堆整数里面选任意两个求和,与限定值比较,问有多少组合符合。这样的话会一瞬间陷入瞎的状态。
我们考虑下,因为最多 2 人,所以如果这两人极限话,分别为这群人里面 最轻,最重的两人
那么问题就比较好办了
最轻+最重 > limit,不好意思,最终的哥们儿你自己搭船走吧,换下一个“最重”的
如果 最轻 + 次最重 <= limit,匹对成功,因为不可能把最轻的换掉,这两个人一条船走吧
如此循环,最后情况就是留下一人或者正好匹配,都是一条船的事情
那么我们可以第一步将这群人按照 轻->重 的顺序拍个号,否则就不能运用上面的逻辑
方法一、升序排列,头尾配对
int cmp(const int *p1, const int *p2)
{
return (*(int *)p1) - (*(int *)p2);
}
int numRescueBoats(int* people, int peopleSize, int limit){
int l=0, r=peopleSize-1;
int cnt=0;
qsort(people, peopleSize, sizeof(int), cmp);
while(l <= r)
{
if(l == r)
{
cnt++;
break;
}
else if(people[l]+people[r] > limit)
{
r--;
cnt++;
}
else
{
l++;
r--;
cnt++;
}
}
return cnt;
}
结束语:
排序我们直接使用了 排序API,非常方便可以按照自己想要的顺序排列好
函数原型:
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));
其中:
base | 指向要排序的数组 |
nitems | 数组大小 |
size | 数组元素类型 |
compar | 函数指针,我们需要自己构建 |
函数指针原型:
int compar(const void *p1, const void *p2);
其中:
升序排列 | 返回值 > 0 |
降序排列 | 返回值 < 0 |
顺序不确定 | 返回值 = 0 |