[LeetCode] 1011. Capacity To Ship Packages Within D Days
A conveyor belt has packages that must be shipped from one port to another within days
days.
The ith
package on the conveyor belt has a weight of weights[i]
. Each day, we load the ship with packages on the conveyor belt (in the order given by weights
). We may not load more weight than the maximum weight capacity of the ship.
Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within days
days.
Example 1:
Input: weights = [1,2,3,4,5,6,7,8,9,10], days = 5 Output: 15 Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this: 1st day: 1, 2, 3, 4, 5 2nd day: 6, 7 3rd day: 8 4th day: 9 5th day: 10 Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.
Example 2:
Input: weights = [3,2,2,4,1,4], days = 3 Output: 6 Explanation: A ship capacity of 6 is the minimum to ship all the packages in 3 days like this: 1st day: 3, 2 2nd day: 2, 4 3rd day: 1, 4
Example 3:
Input: weights = [1,2,3,1,1], days = 4 Output: 3 Explanation: 1st day: 1 2nd day: 2 3rd day: 3 4th day: 1, 1
Constraints:
1 <= days <= weights.length <= 5 * 104
1 <= weights[i] <= 500
在 D 天内送达包裹的能力。
传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意是给一个传送带 weights,传送带上面有一些包裹 i ,他们的重量用 weights[i] 来表示。同时题目给了一个变量 days 表示天数。请问你需要准备运载能力至少为多少的船只,才能确保所有的包裹能在 days 天内全部运走?这里 weights 是一个无序的数组,你只能按顺序读取里面的值,不能对其排序。
思路是二分法。这里二分查找的是船只的运载能力也是属于在答案上二分的题。下界是 weights 中最大的单个货物的重量(因为起码要确保最重的货物可以被运送),上界是 weights 中所有货物的重量总和。在这个范围内二分,去找一个最合适的船只运载重量 mid。每当找到这样一个 mid 的时候,就对 input 数组中的重量累加,并看最后实际需要的船只数量跟 days 的关系。如果 need > days 说明天数太多,需要增加船只运载重量;反之则需要减少船只运载重量。最后返回的是一个满足条件的最小的船只运载重量。我提供两种二分的代码,注意右指针的区别。
时间O(nlogn)
空间O(1)
Java实现一
1 class Solution { 2 public int shipWithinDays(int[] weights, int days) { 3 int right = 0; 4 int left = 0; 5 for (int w : weights) { 6 right += w; 7 left = Math.max(left, w); 8 } 9 10 // mid是在试探每天可行的最大重量 11 while (left <= right) { 12 int mid = left + (right - left) / 2; 13 int need = 1; 14 int curLoad = 0; 15 for (int w : weights) { 16 if (curLoad + w > mid) { 17 need++; 18 curLoad = 0; 19 } 20 curLoad += w; 21 } 22 if (need > days) { 23 left = mid + 1; 24 } else { 25 right = mid - 1; 26 } 27 } 28 return left; 29 } 30 }
Java实现二
1 class Solution { 2 public int shipWithinDays(int[] weights, int days) { 3 // 确定二分查找左右边界 4 int left = Arrays.stream(weights).max().getAsInt(); 5 int right = Arrays.stream(weights).sum(); 6 while (left < right) { 7 int mid = (left + right) / 2; 8 // need 为需要运送的天数 9 // cur 为当前这一天已经运送的包裹重量之和 10 int need = 1, cur = 0; 11 for (int weight : weights) { 12 if (cur + weight > mid) { 13 ++need; 14 cur = 0; 15 } 16 cur += weight; 17 } 18 if (need <= days) { 19 right = mid; 20 } else { 21 left = mid + 1; 22 } 23 } 24 return left; 25 } 26 }
相关题目
774. Minimize Max Distance to Gas Station
1011. Capacity To Ship Packages In N Days
1060. Missing Element in Sorted Array
1231. Divide Chocolate
1283. Find the Smallest Divisor Given a Threshold
1482. Minimum Number of Days to Make m Bouquets