classSolution { public: intshipWithinDays(vector<int>& weights, int days){ // 确定二分查找左右边界 int left = *max_element(weights.begin(), weights.end()), right = accumulate(weights.begin(), weights.end(), 0); while (left < right) { int mid = (left + right) / 2; // need 为需要运送的天数 // cur 为当前这一天已经运送的包裹重量之和 int need = 1, cur = 0; for (int weight: weights) { if (cur + weight > mid) { ++need; cur = 0; } cur += weight; } if (need <= days) { right = mid; } else { left = mid + 1; } } return left; } };
classSolution: defshipWithinDays(self, weights: List[int], days: int) -> int: # 确定二分查找左右边界 left, right = max(weights), sum(weights) while left < right: mid = (left + right) // 2 # need 为需要运送的天数 # cur 为当前这一天已经运送的包裹重量之和 need, cur = 1, 0 for weight in weights: if cur + weight > mid: need += 1 cur = 0 cur += weight if need <= days: right = mid else: left = mid + 1 return left
var shipWithinDays = function(weights, days) { // 确定二分查找左右边界 let left = Math.max(...weights), right = weights.reduce((a, b) => a + b); while (left < right) { const mid = Math.floor((left + right) / 2); // need 为需要运送的天数 // cur 为当前这一天已经运送的包裹重量之和 let need = 1, cur = 0; for (const weight of weights) { if (cur + weight > mid) { need++; cur = 0; } cur += weight; }
if (need <= days) { right = mid; } else { left = mid + 1; } } return left; };
funcshipWithinDays(weights []int, days int)int { // 确定二分查找左右边界 left, right := 0, 0 for _, w := range weights { if w > left { left = w } right += w } return left + sort.Search(right-left, func(x int)bool { x += left day := 1// 需要运送的天数 sum := 0// 当前这一天已经运送的包裹重量之和 for _, w := range weights { if sum+w > x { day++ sum = 0 } sum += w } return day <= days }) }
intshipWithinDays(int* weights, int weightsSize, int days) { // 确定二分查找左右边界 int left = 0, right = 0; for (int i = 0; i < weightsSize; i++) { left = fmax(left, weights[i]); right += weights[i]; } while (left < right) { int mid = (left + right) / 2; // need 为需要运送的天数 // cur 为当前这一天已经运送的包裹重量之和 int need = 1, cur = 0; for (int i = 0; i < weightsSize; i++) { if (cur + weights[i] > mid) { ++need; cur = 0; } cur += weights[i]; } if (need <= days) { right = mid; } else { left = mid + 1; } } return left; }
复杂度分析
时间复杂度:O\big(n\log(\Sigma w)\big),其中 n 是数组 weights 的长度,\Sigma w 是数组 weights 中元素的和。二分查找需要执行的次数为 O(\log(\Sigma w)),每一步中需要对数组 weights 进行依次遍历,时间为 O(n),相乘即可得到总时间复杂度。