【Leetcode】881. 救生艇

文章目录

题目

点击打开题目链接🔗

给定数组 p e o p l e people people 。 p e o p l e i peoplei peoplei表示第 i i i 个人的体重 ,船的数量不限 ,每艘船可以承载的最大重量为 l i m i t limit limit。

每艘船最多可同时载两人 ,但条件是这些人的重量之和最多为 l i m i t 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 ≤ p e o p l e . l e n g t h ≤ 5 ∗ 1 0 4 1 \leq people.length \leq 5 * 10^4 1≤people.length≤5∗104
1 ≤ p e o p l e i ≤ l i m i t ≤ 3 ∗ 1 0 4 1 \leq peoplei \leq limit \leq 3 * 10^4 1≤peoplei≤limit≤3∗104

思路

为了最小化船只的数量,可以使用贪心的策略,可以想到将最轻的人和最重的人安排在一起,如果他们的重量之和小于或者是等于 l i m i t limit limit,那么他们就是可以一起坐在一艘船,然后我们在剩下的人中继续找最轻的和最重的继续验证;如果最轻的和最重的不能坐一艘船,那么最重的人和剩下的任意一个人都无法配对坐同一艘船,最重的那个人需要独自坐一艘船;以上反复操作知道全部人分配完毕。

总结一下步骤:

  1. 首先,将数组 people 进行排序,这样可以方便地从最轻和最重的人开始配对
  2. 使用两个指针:一个指向最轻的人的起始位置(左指针),一个指向最重的人的末尾位置(右指针)
  3. 尝试将最轻和最重的人配对。如果他们的体重之和小于或等于 limit,他们可以一起坐一艘船,此时左指针右移,右指针左移。
  4. 如果最轻和最重的人不能一起坐一艘船(即他们的体重之和大于 limit),那么最重的人独自坐一艘船,此时右指针左移
  5. 每次操作,船的数量加一
  6. 步骤 3 3 3、 4 4 4、 5 5 5重复执行直到所有的人都安排到船上

代码

c++ 复制代码
class Solution {
public:
    int numRescueBoats(vector<int>& people, int limit) {
        sort(people.begin(),people.end());
        int minboat=0;
        for(int left=0,right=people.size()-1;left<=right;right--)
        {
            if(people[left]+people[right]<=limit)left++;
            minboat++;
        }
        return minboat;
    }
};

复杂度分析

时间复杂度

  • 排序的时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),其中这个 n n n是数组 p e o p l e people people的长度
  • 双指针遍历数组的时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)
    因此总的时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

空间复杂度

  • 排序的空间复杂度取决于排序的算法。在C++中, s o r t sort sort函数通常使用的是 i n t r o s o r t introsort introsort,其空间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
  • 其余部分使用的空间为常数级别为 O ( 1 ) O(1) O(1)
    总的来说空间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

结果



ps:这里不太清楚为啥空间复杂度能干到常数级别,可能是因为数组长度太小了只有 5 ∗ 1 0 4 5 * 10^4 5∗104?有没有大佬说说

总结

该问题使用贪心算法和双指针技巧,通过先排序,再使用双指针从最轻和最重的人开始配对,使得每次尽可能转俩人,从而最小化所需要的船的数量。

相关推荐
basketball6167 分钟前
C++ 中字符串与常见类型的转换总结
开发语言·c++
文丑颜不良啊26 分钟前
LeetCode276~300题目解析
java·leetcode
荆棘鸟智能28 分钟前
短历时洪水预报算法实践:水文模型与 LightGBM 残差订正融合
人工智能·算法·机器人
wuyk55531 分钟前
《WiFi 嵌入式物联网开发全套实战》 | 第 45 章【终章】WiFi 开发全套知识复盘 + 面试高频题 + 进阶路线
物联网·面试·职场和发展
等我调个Bug33 分钟前
C++智能指针通俗讲解
开发语言·c++
葫三生1 小时前
关于三生原理系列被技术开发社区批量收录或引发策展边界讨论的一种思考
大数据·人工智能·深度学习·算法·机器学习·数据挖掘·开源
catcatuncle1 小时前
OpenWorkBuddy 部署排错手册:从源码启动到自己搭一个给团队用,七个最容易卡住的地方
算法
avi91111 小时前
【AI教人】在Inspector显示所有Delegate-Odin Inspector之三
java·前端·算法·delegate·inspector·editor扩展·unity editor
淡海水1 小时前
06-02-源码-增量标记算法实现
算法·unity·c#·gc
碧海银沙音频科技研究院2 小时前
实现炬芯ATS308X的usb cdc 串口IAP 固件升级功能实现
人工智能·嵌入式硬件·深度学习·算法