当前位置: 首页 > news >正文

二分查找解力扣1011最优运载能力

问题解析:力扣1011 题 “在 D 天内送达包裹的能力” 要求确定在给定天数D内,将所有包裹从传送带上运完的最低运载能力。运载能力capacity表示船每天能运送的最大重量,且必须按数组顺序运送,每天运送的总重量不能超过capacity

核心思路:这是一个二分查找问题。运载能力capacity存在一个可行域

  • 下界left:至少需要能运走最重的单个包裹,即max(weights)
  • 上界right:最坏情况一天运完所有包裹,即sum(weights)
    [left, right]范围内,对于任意一个capacity,我们可以通过模拟运送过程计算出所需天数needDays。根据needDaysD的关系来调整二分查找的边界:
    *若needDays <= D,说明当前运力充足或刚好,可以尝试减小运力(缩小右边界)。
  • needDays > D,说明当前运力不足,必须增大运力(增大左边界)。
    最终,left即为所求的最小运力。

C++ 代码实现

class Solution { public: int shipWithinDays(vector<int>& weights, int D) { // 确定二分查找的左右边界 int left = *max_element(weights.begin(), weights.end()); // 运力至少能装下最重的包裹 int right = accumulate(weights.begin(), weights.end(), 0); // 运力最多一天运完所有 while (left < right) { int mid = left + (right - left) / 2; // 当前尝试的运力 int need = 1; // 需要运送的天数,初始为1天 int cur = 0; // 当前这一天已经装载的重量 // 模拟以 mid 为运力,运送所有包裹所需的天数 for (int weight : weights) { if (cur + weight > mid) { // 如果加上当前包裹会超载 ++need; // 则需要新的一天 cur = weight; // 新的一天从当前包裹开始装 } else { cur += weight; // 没超载,继续装 } } // 根据所需天数调整二分边界 if (need <= D) { right = mid; // 运力足够或有余,尝试更小的运力 } else { left = mid + 1; // 运力不足,必须增大 } } return left; // 此时 left == right,即为最小运力 } };

代码说明

  1. 边界初始化left初始化为数组最大值,right初始化为数组总和 。
  2. 二分查找循环:当left < right时,计算中间值mid作为尝试的运力。
  3. 模拟运送函数(内嵌循环):遍历所有包裹,累加当前天的重量cur。若加上当前包裹后重量超过mid,则天数need加一,并在新的一天开始运送该包裹 。
  4. 边界调整
    • 若计算出的所需天数need小于等于D,说明运力mid可行,为了寻找最小运力,将搜索范围缩小至左半部分 (right = mid)。
    • need大于D,说明运力mid不足,需增大运力,将搜索范围调整至右半部分 (left = mid + 1)。
  5. 返回值:循环结束时leftright相等,即为满足条件的最小运力。
  6. 复杂度分析
    • 时间复杂度:O(n log m),其中n是包裹数量,m是包裹总重量。二分查找复杂度为 O(log m),每次模拟运送需要 O(n)。
    • 空间复杂度:O(1),只使用了常数个额外变量。

示例
输入:weights = [1,2,3,4,5,6,7,8,9,10],D = 5

  1. left = 10,right = 55
  2. 第一次尝试mid = (10+55)/2 = 32,模拟运送:[1,2,3,4,5,6,7,8](36>32,分两天),[9,10],共需3天 (need=3)。3 <= 5,所以right = 32
  3. 继续二分,最终找到最小运力为15。验证:以运力15运送,[1,2,3,4,5],[6,7],[8],[9],[10]正好需要5天。

参考来源

  • LeetCode1011
  • ❤️67❤️带新手一起刷力扣 (LeetCode)❤️代码有详细的注释❤️反思总结❤️67. 二进制求和
  • 力扣67-二进制求和-C++
  • Leetcode 693. 交替位二进制数 C++
  • Leetcode 67. 二进制求和 C++
http://www.jsqmd.com/news/1148730/

相关文章:

  • ADP5350与STM32F205RB嵌入式电源管理方案解析
  • ADP5350与STM32F215ZG电源管理方案设计与优化
  • 3分钟快速解密QQ聊天记录数据库:全平台密钥提取终极指南
  • 25个Obsidian终极模板:快速构建你的个人知识管理系统
  • 3秒定位:当手机号成为你的地理侦探,工作效率提升80%的秘密武器
  • 5秒破解百度网盘提取码:开源智能工具终极使用指南
  • 大疆极飞无人机如何将2026年免费高清地图录入遥控器
  • AI 电动搅拌机智能功率 MOSFET 完整选型方案
  • 数字孪生智慧仓储物流系统如何选型?从技术架构与产品能力对比看未来发展趋势
  • 55项功能全解锁:HsMod炉石传说增强插件完全指南
  • JetBrains Air:IDE底层重写的多Agent智能编程架构
  • Windows B站客户端终极指南:告别网页卡顿,享受原生流畅体验
  • 上下文工程:AI 智能体为什么离不开它?
  • 使用 Elasticsearch 作为 Grafana 的直接替代 Prometheus 后端
  • GHelper终极指南:5分钟快速掌控华硕笔记本性能的免费神器
  • Node.js Worker Threads 实战:CPU 密集型任务的线程池设计与性能对比
  • EM3080-W与PIC18F65K40的嵌入式条形码识别系统设计
  • 5分钟轻松实现:基于ASP.NET的手机号码定位系统开发指南
  • 墨迹天气 API 常见错误与排错指南
  • caret 6.0.94 RFE 实战:3种模型(线性回归/随机森林/SVM)特征选择性能对比
  • yolo settings命令使用示例:自定义训练权重保存路径runs_dir
  • 深度解析:基于Java的GB28181视频监控平台架构设计与高并发实现
  • Telegram AI Bot自动化实战:5步用Make搭建业务工作台
  • 如何3秒定位手机号码位置:免费开源工具实战秘籍
  • 5分钟快速上手:用XUnity.AutoTranslator为Unity游戏添加中文翻译
  • 小红书下载神器:XHS-Downloader 终极使用指南,轻松保存心仪内容
  • 苹果18 AI图像生成工具:本地部署、API集成与性能优化实战
  • 深度解析百度网盘链接解析工具的技术架构设计与性能优化实践
  • 为什么原函数的垂直渐近线,会导致导函数在相同位置也是垂直渐近线?(且符号可能相反)
  • 终极指南:3分钟解锁索尼相机隐藏功能,享受完全自定义体验