Skip to content

Commit c3b51eb

Browse files
committed
feat: add solutions to lc problem: No.1011
No.1011.Capacity To Ship Packages Within D Days
1 parent 86a69f1 commit c3b51eb

File tree

7 files changed

+276
-230
lines changed

7 files changed

+276
-230
lines changed

solution/1000-1099/1011.Capacity To Ship Packages Within D Days/README.md

Lines changed: 99 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70-
二分查找
70+
**方法一:二分查找**
7171

72-
二分枚举运载能力 capacity,找到能在 D 天内送达的最小运载。
72+
我们注意到,如果运载能力 $x$ 能够在 $days$ 天内运送完所有包裹,那么运载能力 $x + 1$ 也能在 $days$ 天内运送完所有包裹。也即是说,随着运载能力的增加,运送天数只会减少,不会增加。这存在一个单调性,因此我们可以使用二分查找的方法来寻找最小的运载能力。
73+
74+
我们定义二分查找的左边界 $left= \max\limits_{i=0}^{n-1} weights[i]$,右边界 $right = \sum\limits_{i=0}^{n-1} weights[i]$。然后二分枚举运载能力 $x$,判断是否能在 $days$ 天内运送完所有包裹。如果能,那么我们将右边界调整为 $x$,否则将左边界调整为 $x + 1$。
75+
76+
判断是否能在 $days$ 天内运送完所有包裹的方法是,我们从左到右遍历包裹,将当前包裹加入当前运载能力的船上,如果当前船的运载能力超过了 $x$,那么我们将当前包裹放到下一天的船上,同时天数加一。如果天数超过了 $days$,那么我们返回 $false$,否则返回 $true$。
77+
78+
时间复杂度 $O(n \times \log \sum\limits_{i=0}^{n-1} weights[i])$,空间复杂度 $O(1)$。其中 $n$ 为包裹数量。
7379

7480
<!-- tabs:start -->
7581

@@ -79,27 +85,18 @@
7985

8086
```python
8187
class Solution:
82-
def shipWithinDays(self, weights: List[int], D: int) -> int:
83-
def check(capacity):
84-
cnt, t = 1, 0
88+
def shipWithinDays(self, weights: List[int], days: int) -> int:
89+
def check(mx):
90+
ws, cnt = 0, 1
8591
for w in weights:
86-
if w > capacity:
87-
return False
88-
if t + w <= capacity:
89-
t += w
90-
else:
92+
ws += w
93+
if ws > mx:
9194
cnt += 1
92-
t = w
93-
return cnt <= D
94-
95-
left, right = 1, 25000000
96-
while left < right:
97-
mid = (left + right) >> 1
98-
if check(mid):
99-
right = mid
100-
else:
101-
left = mid + 1
102-
return left
95+
ws = w
96+
return cnt <= days
97+
98+
left, right = max(weights), sum(weights) + 1
99+
return left + bisect_left(range(left, right), True, key=check)
103100
```
104101

105102
### **Java**
@@ -109,10 +106,14 @@ class Solution:
109106
```java
110107
class Solution {
111108
public int shipWithinDays(int[] weights, int days) {
112-
int left = 1, right = Integer.MAX_VALUE;
109+
int left = 0, right = 0;
110+
for (int w : weights) {
111+
left = Math.max(left, w);
112+
right += w;
113+
}
113114
while (left < right) {
114115
int mid = (left + right) >> 1;
115-
if (canCarry(weights, days, mid)) {
116+
if (check(mid, weights, days)) {
116117
right = mid;
117118
} else {
118119
left = mid + 1;
@@ -121,21 +122,16 @@ class Solution {
121122
return left;
122123
}
123124

124-
public boolean canCarry(int[] weights, int days, int carry) {
125-
int useDay = 1;
126-
int curCarry = 0;
127-
for (int weight : weights) {
128-
if (weight > carry) {
129-
return false;
130-
}
131-
if ((carry - curCarry) >= weight) {
132-
curCarry += weight;
133-
} else {
134-
curCarry = weight;
135-
useDay++;
125+
private boolean check(int mx, int[] weights, int days) {
126+
int ws = 0, cnt = 1;
127+
for (int w : weights) {
128+
ws += w;
129+
if (ws > mx) {
130+
ws = w;
131+
++cnt;
136132
}
137133
}
138-
return useDay <= days;
134+
return cnt <= days;
139135
}
140136
}
141137
```
@@ -146,66 +142,92 @@ class Solution {
146142
class Solution {
147143
public:
148144
int shipWithinDays(vector<int>& weights, int days) {
149-
int left = 1, right = 25000000;
145+
int left = 0, right = 0;
146+
for (auto& w : weights) {
147+
left = max(left, w);
148+
right += w;
149+
}
150+
auto check = [&](int mx) {
151+
int ws = 0, cnt = 1;
152+
for (auto& w : weights) {
153+
ws += w;
154+
if (ws > mx) {
155+
ws = w;
156+
++cnt;
157+
}
158+
}
159+
return cnt <= days;
160+
};
150161
while (left < right) {
151-
int mid = left + right >> 1;
152-
if (check(weights, days, mid)) {
162+
int mid = (left + right) >> 1;
163+
if (check(mid)) {
153164
right = mid;
154165
} else {
155166
left = mid + 1;
156167
}
157168
}
158169
return left;
159170
}
160-
161-
bool check(vector<int>& weights, int days, int capacity) {
162-
int cnt = 1, t = 0;
163-
for (auto w : weights) {
164-
if (w > capacity) {
165-
return false;
166-
}
167-
if (t + w <= capacity) {
168-
t += w;
169-
} else {
170-
++cnt;
171-
t = w;
172-
}
173-
}
174-
return cnt <= days;
175-
}
176171
};
177172
```
178173
179174
### **Go**
180175
181176
```go
182177
func shipWithinDays(weights []int, days int) int {
183-
left, right := 1, 25000000
184-
for left < right {
185-
mid := (left + right) >> 1
186-
if check(weights, days, mid) {
187-
right = mid
188-
} else {
189-
left = mid + 1
178+
var left, right int
179+
for _, w := range weights {
180+
if left < w {
181+
left = w
190182
}
183+
right += w
191184
}
192-
return left
185+
return left + sort.Search(right, func(mx int) bool {
186+
mx += left
187+
ws, cnt := 0, 1
188+
for _, w := range weights {
189+
ws += w
190+
if ws > mx {
191+
ws = w
192+
cnt++
193+
}
194+
}
195+
return cnt <= days
196+
})
193197
}
198+
```
194199

195-
func check(weights []int, days, capacity int) bool {
196-
cnt, t := 1, 0
197-
for _, w := range weights {
198-
if w > capacity {
199-
return false
200-
}
201-
if t+w <= capacity {
202-
t += w
203-
} else {
204-
cnt++
205-
t = w
206-
}
207-
}
208-
return cnt <= days
200+
### **TypeScript**
201+
202+
```ts
203+
function shipWithinDays(weights: number[], days: number): number {
204+
let left = 0;
205+
let right = 0;
206+
for (const w of weights) {
207+
left = Math.max(left, w);
208+
right += w;
209+
}
210+
const check = (mx: number) => {
211+
let ws = 0;
212+
let cnt = 1;
213+
for (const w of weights) {
214+
ws += w;
215+
if (ws > mx) {
216+
ws = w;
217+
++cnt;
218+
}
219+
}
220+
return cnt <= days;
221+
};
222+
while (left < right) {
223+
const mid = (left + right) >> 1;
224+
if (check(mid)) {
225+
right = mid;
226+
} else {
227+
left = mid + 1;
228+
}
229+
}
230+
return left;
209231
}
210232
```
211233

0 commit comments

Comments
 (0)