Skip to content

Commit 18ed78e

Browse files
authored
feat: add solutions to lc problem: No.0875 (#2627)
No.0875.Koko Eating Bananas
1 parent 8fb80ad commit 18ed78e

File tree

11 files changed

+205
-173
lines changed

11 files changed

+205
-173
lines changed

solution/0800-0899/0875.Koko Eating Bananas/README.md

+68-57
Original file line numberDiff line numberDiff line change
@@ -56,43 +56,40 @@
5656

5757
### 方法一:二分查找
5858

59-
二分枚举速度值,找到能在 $h$ 小时内吃完所有香蕉的最小速度值
59+
我们注意到,如果珂珂能够以 $k$ 的速度在 $h$ 小时内吃完所有香蕉,那么她也可以以 $k' > k$ 的速度在 $h$ 小时内吃完所有香蕉。这存在着单调性,因此我们可以使用二分查找,找到最小的满足条件的 $k$
6060

61-
时间复杂度 $O(n\log m)$,空间复杂度 $O(1)$。其中 $n$ 是 `piles` 的长度,而 $m$ 是 `piles` 中的最大值。
61+
我们定义二分查找的左边界 $l = 1$,右边界 $r = \max(\text{piles})$。每一次二分,我们取中间值 $mid = \frac{l + r}{2}$,然后计算以 $mid$ 的速度吃香蕉需要的时间 $s$。如果 $s \leq h$,说明 $mid$ 的速度可以满足条件,我们将右边界 $r$ 更新为 $mid$;否则,我们将左边界 $l$ 更新为 $mid + 1$。最终,当 $l = r$ 时,我们找到了最小的满足条件的 $k$。
62+
63+
时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组 `piles` 的长度和最大值。空间复杂度 $O(1)$。
6264

6365
<!-- tabs:start -->
6466

6567
```python
6668
class Solution:
6769
def minEatingSpeed(self, piles: List[int], h: int) -> int:
68-
left, right = 1, int(1e9)
69-
while left < right:
70-
mid = (left + right) >> 1
71-
s = sum((x + mid - 1) // mid for x in piles)
72-
if s <= h:
73-
right = mid
74-
else:
75-
left = mid + 1
76-
return left
70+
def check(k: int) -> bool:
71+
return sum((x + k - 1) // k for x in piles) <= h
72+
73+
return 1 + bisect_left(range(1, max(piles) + 1), True, key=check)
7774
```
7875

7976
```java
8077
class Solution {
8178
public int minEatingSpeed(int[] piles, int h) {
82-
int left = 1, right = (int) 1e9;
83-
while (left < right) {
84-
int mid = (left + right) >>> 1;
79+
int l = 1, r = (int) 1e9;
80+
while (l < r) {
81+
int mid = (l + r) >> 1;
8582
int s = 0;
8683
for (int x : piles) {
8784
s += (x + mid - 1) / mid;
8885
}
8986
if (s <= h) {
90-
right = mid;
87+
r = mid;
9188
} else {
92-
left = mid + 1;
89+
l = mid + 1;
9390
}
9491
}
95-
return left;
92+
return l;
9693
}
9794
}
9895
```
@@ -101,30 +98,31 @@ class Solution {
10198
class Solution {
10299
public:
103100
int minEatingSpeed(vector<int>& piles, int h) {
104-
int left = 1, right = 1e9;
105-
while (left < right) {
106-
int mid = (left + right) >> 1;
101+
int l = 1, r = ranges::max(piles);
102+
while (l < r) {
103+
int mid = (l + r) >> 1;
107104
int s = 0;
108-
for (int& x : piles) s += (x + mid - 1) / mid;
109-
if (s <= h)
110-
right = mid;
111-
else
112-
left = mid + 1;
105+
for (int x : piles) {
106+
s += (x + mid - 1) / mid;
107+
}
108+
if (s <= h) {
109+
r = mid;
110+
} else {
111+
l = mid + 1;
112+
}
113113
}
114-
return left;
114+
return l;
115115
}
116116
};
117117
```
118118
119119
```go
120120
func minEatingSpeed(piles []int, h int) int {
121-
return sort.Search(1e9, func(i int) bool {
122-
if i == 0 {
123-
return false
124-
}
121+
return 1 + sort.Search(slices.Max(piles), func(k int) bool {
122+
k++
125123
s := 0
126124
for _, x := range piles {
127-
s += (x + i - 1) / i
125+
s += (x + k - 1) / k
128126
}
129127
return s <= h
130128
})
@@ -133,46 +131,59 @@ func minEatingSpeed(piles []int, h int) int {
133131

134132
```ts
135133
function minEatingSpeed(piles: number[], h: number): number {
136-
let left = 1;
137-
let right = Math.max(...piles);
138-
while (left < right) {
139-
const mid = (left + right) >> 1;
140-
let s = 0;
141-
for (const x of piles) {
142-
s += Math.ceil(x / mid);
143-
}
134+
let [l, r] = [1, Math.max(...piles)];
135+
while (l < r) {
136+
const mid = (l + r) >> 1;
137+
const s = piles.map(x => Math.ceil(x / mid)).reduce((a, b) => a + b);
144138
if (s <= h) {
145-
right = mid;
139+
r = mid;
146140
} else {
147-
left = mid + 1;
141+
l = mid + 1;
148142
}
149143
}
150-
return left;
144+
return l;
145+
}
146+
```
147+
148+
```rust
149+
impl Solution {
150+
pub fn min_eating_speed(piles: Vec<i32>, h: i32) -> i32 {
151+
let mut l = 1;
152+
let mut r = *piles.iter().max().unwrap_or(&0);
153+
while l < r {
154+
let mid = (l + r) >> 1;
155+
let mut s = 0;
156+
for x in piles.iter() {
157+
s += (x + mid - 1) / mid;
158+
}
159+
if s <= h {
160+
r = mid;
161+
} else {
162+
l = mid + 1;
163+
}
164+
}
165+
l
166+
}
151167
}
152168
```
153169

154170
```cs
155171
public class Solution {
156172
public int MinEatingSpeed(int[] piles, int h) {
157-
int left = 1, right = piles.Max();
158-
while (left < right)
159-
{
160-
int mid = (left + right) >> 1;
173+
int l = 1, r = (int) 1e9;
174+
while (l < r) {
175+
int mid = (l + r) >> 1;
161176
int s = 0;
162-
foreach (int pile in piles)
163-
{
164-
s += (pile + mid - 1) / mid;
165-
}
166-
if (s <= h)
167-
{
168-
right = mid;
177+
foreach (int x in piles) {
178+
s += (x + mid - 1) / mid;
169179
}
170-
else
171-
{
172-
left = mid + 1;
180+
if (s <= h) {
181+
r = mid;
182+
} else {
183+
l = mid + 1;
173184
}
174185
}
175-
return left;
186+
return l;
176187
}
177188
}
178189
```

solution/0800-0899/0875.Koko Eating Bananas/README_EN.md

+71-56
Original file line numberDiff line numberDiff line change
@@ -47,41 +47,42 @@
4747

4848
## Solutions
4949

50-
### Solution 1
50+
### Solution 1: Binary Search
51+
52+
We notice that if Koko can eat all the bananas at a speed of $k$ within $h$ hours, then she can also eat all the bananas at a speed of $k' > k$ within $h$ hours. This shows monotonicity, so we can use binary search to find the smallest $k$ that satisfies the condition.
53+
54+
We define the left boundary of the binary search as $l = 1$, and the right boundary as $r = \max(\text{piles})$. For each binary search, we take the middle value $mid = \frac{l + r}{2}$, and then calculate the time $s$ required to eat bananas at a speed of $mid$. If $s \leq h$, it means that the speed of $mid$ can meet the condition, and we update the right boundary $r$ to $mid$; otherwise, we update the left boundary $l$ to $mid + 1$. Finally, when $l = r$, we find the smallest $k$ that satisfies the condition.
55+
56+
The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the length and maximum value of the array `piles` respectively. The space complexity is $O(1)$.
5157

5258
<!-- tabs:start -->
5359

5460
```python
5561
class Solution:
5662
def minEatingSpeed(self, piles: List[int], h: int) -> int:
57-
left, right = 1, int(1e9)
58-
while left < right:
59-
mid = (left + right) >> 1
60-
s = sum((x + mid - 1) // mid for x in piles)
61-
if s <= h:
62-
right = mid
63-
else:
64-
left = mid + 1
65-
return left
63+
def check(k: int) -> bool:
64+
return sum((x + k - 1) // k for x in piles) <= h
65+
66+
return 1 + bisect_left(range(1, max(piles) + 1), True, key=check)
6667
```
6768

6869
```java
6970
class Solution {
7071
public int minEatingSpeed(int[] piles, int h) {
71-
int left = 1, right = (int) 1e9;
72-
while (left < right) {
73-
int mid = (left + right) >>> 1;
72+
int l = 1, r = (int) 1e9;
73+
while (l < r) {
74+
int mid = (l + r) >> 1;
7475
int s = 0;
7576
for (int x : piles) {
7677
s += (x + mid - 1) / mid;
7778
}
7879
if (s <= h) {
79-
right = mid;
80+
r = mid;
8081
} else {
81-
left = mid + 1;
82+
l = mid + 1;
8283
}
8384
}
84-
return left;
85+
return l;
8586
}
8687
}
8788
```
@@ -90,30 +91,31 @@ class Solution {
9091
class Solution {
9192
public:
9293
int minEatingSpeed(vector<int>& piles, int h) {
93-
int left = 1, right = 1e9;
94-
while (left < right) {
95-
int mid = (left + right) >> 1;
94+
int l = 1, r = ranges::max(piles);
95+
while (l < r) {
96+
int mid = (l + r) >> 1;
9697
int s = 0;
97-
for (int& x : piles) s += (x + mid - 1) / mid;
98-
if (s <= h)
99-
right = mid;
100-
else
101-
left = mid + 1;
98+
for (int x : piles) {
99+
s += (x + mid - 1) / mid;
100+
}
101+
if (s <= h) {
102+
r = mid;
103+
} else {
104+
l = mid + 1;
105+
}
102106
}
103-
return left;
107+
return l;
104108
}
105109
};
106110
```
107111
108112
```go
109113
func minEatingSpeed(piles []int, h int) int {
110-
return sort.Search(1e9, func(i int) bool {
111-
if i == 0 {
112-
return false
113-
}
114+
return 1 + sort.Search(slices.Max(piles), func(k int) bool {
115+
k++
114116
s := 0
115117
for _, x := range piles {
116-
s += (x + i - 1) / i
118+
s += (x + k - 1) / k
117119
}
118120
return s <= h
119121
})
@@ -122,46 +124,59 @@ func minEatingSpeed(piles []int, h int) int {
122124

123125
```ts
124126
function minEatingSpeed(piles: number[], h: number): number {
125-
let left = 1;
126-
let right = Math.max(...piles);
127-
while (left < right) {
128-
const mid = (left + right) >> 1;
129-
let s = 0;
130-
for (const x of piles) {
131-
s += Math.ceil(x / mid);
132-
}
127+
let [l, r] = [1, Math.max(...piles)];
128+
while (l < r) {
129+
const mid = (l + r) >> 1;
130+
const s = piles.map(x => Math.ceil(x / mid)).reduce((a, b) => a + b);
133131
if (s <= h) {
134-
right = mid;
132+
r = mid;
135133
} else {
136-
left = mid + 1;
134+
l = mid + 1;
137135
}
138136
}
139-
return left;
137+
return l;
138+
}
139+
```
140+
141+
```rust
142+
impl Solution {
143+
pub fn min_eating_speed(piles: Vec<i32>, h: i32) -> i32 {
144+
let mut l = 1;
145+
let mut r = *piles.iter().max().unwrap_or(&0);
146+
while l < r {
147+
let mid = (l + r) >> 1;
148+
let mut s = 0;
149+
for x in piles.iter() {
150+
s += (x + mid - 1) / mid;
151+
}
152+
if s <= h {
153+
r = mid;
154+
} else {
155+
l = mid + 1;
156+
}
157+
}
158+
l
159+
}
140160
}
141161
```
142162

143163
```cs
144164
public class Solution {
145165
public int MinEatingSpeed(int[] piles, int h) {
146-
int left = 1, right = piles.Max();
147-
while (left < right)
148-
{
149-
int mid = (left + right) >> 1;
166+
int l = 1, r = (int) 1e9;
167+
while (l < r) {
168+
int mid = (l + r) >> 1;
150169
int s = 0;
151-
foreach (int pile in piles)
152-
{
153-
s += (pile + mid - 1) / mid;
154-
}
155-
if (s <= h)
156-
{
157-
right = mid;
170+
foreach (int x in piles) {
171+
s += (x + mid - 1) / mid;
158172
}
159-
else
160-
{
161-
left = mid + 1;
173+
if (s <= h) {
174+
r = mid;
175+
} else {
176+
l = mid + 1;
162177
}
163178
}
164-
return left;
179+
return l;
165180
}
166181
}
167182
```

0 commit comments

Comments
 (0)