力扣1011题详解:船只装载问题的二分查找优化解法(C++代码实现)

一、题目解读
力扣1011题要求在给定的货物重量数组中,计算船只每天最多装载一定重量时,最少需要多少天完成运输。题目关键在于找到满足天数限制的最小最大载重量,属于典型的查找最值问题。
二、解题思路
采用二分查找算法。核心思想是将问题转化为:是否存在一个载重量阈值,使得按该阈值分配货物时,所需天数不超过给定天数。通过二分查找该阈值,降低时间复杂度。
三、解题步骤
1. 确定二分边界:左边界为最大货物重量(单日至少载1件),右边界为总重量(单日载完);
2. 二分查找:每次计算中间值mid对应的所需天数;
3. 模拟装载:遍历货物,若当前累计重量超mid,天数递增并重置累计;
4. 调整边界:若天数≤给定天数,说明阈值可能更小(右移),否则需更大(左移);
5. 返回最终左边界(因循环结束时left=right)。
四、代码与注释
class Solution {
public:
int shipWithinDays(vector<int>& weights, int days) {
// 确定二分查找的左右边界
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 current = 0; // 当前运载量
int need = 1; // 需要的天数
// 计算当前运载能力下需要的天数
for (int w : weights) {
if (current + w > mid) {
need++;
current = 0;
}
current += w;
}
// 调整二分查找边界
if (need <= days) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
};注释解析:
● left/right初始化为合理边界,避免无效查找;
● 内部循环通过模拟装载判断mid可行性;
● 时间复杂度O(nlogsum),n为货物数,sum为总重量。
五、总结
本题通过将“求最小满足条件值”转化为二分查找,巧妙利用单调性优化。关键在于设计合理的二分判定条件(模拟装载过程),以及边界值的正确初始化。掌握此类转换思路可高效解决类似最值查找问题。
原创内容 转载请注明出处





