-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathkoko-eating-bananas.py
196 lines (167 loc) · 5.68 KB
/
koko-eating-bananas.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"""
875. Koko Eating Bananas
Medium
Share
Koko loves to eat bananas. There are n piles of bananas, the ith pile has piles[i] bananas. The guards have gone and will come back in h hours.
Koko can decide her bananas-per-hour eating speed of k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour.
Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.
Return the minimum integer k such that she can eat all the bananas within h hours.
Example 1:
Input: piles = [3,6,7,11], h = 8
Output: 4
Example 2:
Input: piles = [30,11,23,4,20], h = 5
Output: 30
Example 3:
Input: piles = [30,11,23,4,20], h = 6
Output: 23
Constraints:
1 <= piles.length <= 104
piles.length <= h <= 109
1 <= piles[i] <= 109
"""
# V0
# IDEA : BINARY SEARCH
import math
class Solution(object):
def minEatingSpeed(self, piles, h):
def help(piles, speed):
res = 0
for p in piles:
# NOTE !!! we use math.ceil here
res += math.ceil(p / speed)
return res
# edge case
if not piles:
return 0
# binary search
piles.sort()
"""
NOTE !!! we init l as 1, r as piles[-1] (or max(piles))
"""
l = 1
r = piles[-1]
while r >= l:
mid = l + (r - l) // 2
_hour = help(piles, mid)
#print ("mid = " + str(mid) + " _hour = " + str(_hour) + " h = " + str(h))
"""
NOTE !!! the binary search boundary condition is a bit different here:
-> if _hour <= h (not "<=" !!!)
-> we make r = mid -1
-> else
-> l = mid + 1
"""
if _hour <= h:
r = mid - 1
else:
l = mid + 1
### NOTE : return l, since we minimum integer k (hour) that fit the condition
return l
# V1
# IDEA : BINARY SEARCH
# https://leetcode.com/problems/koko-eating-bananas/solution/
class Solution:
def minEatingSpeed(self, piles, h):
# Initalize the left and right boundaries
left = 1
right = max(piles)
while left < right:
# Get the middle index between left and right boundary indexes.
# hour_spent stands for the total hour Koko spends.
middle = (left + right) // 2
hour_spent = 0
# Iterate over the piles and calculate hour_spent.
# We increase the hour_spent by ceil(pile / middle)
for pile in piles:
# python ceil : https://www.runoob.com/python/func-number-ceil.html
hour_spent += math.ceil(pile / middle)
# Check if middle is a workable speed, and cut the search space by half.
if hour_spent <= h:
right = middle
else:
left = middle + 1
# Once the left and right boundaries coincide, we find the target value,
# that is, the minimum workable eating speed.
return right
# V1'
# IDEA : BRUTE FORCE
# https://leetcode.com/problems/koko-eating-bananas/solution/
class Solution:
def minEatingSpeed(self, piles, h):
#Start at an eating speed of 1.
speed = 1
while True:
# hour_spent stands for the total hour Koko spends with
# the given eating speed.
hour_spent = 0
# Iterate over the piles and calculate hour_spent.
# We increase the hour_spent by ceil(pile / speed)
for pile in piles:
hour_spent += math.ceil(pile / speed)
# Check if Koko can finish all the piles within h hours,
# If so, return speed. Otherwise, let speed increment by
# 1 and repeat the previous iteration.
if hour_spent <= h:
return speed
else:
speed += 1
# V1''
# https://blog.csdn.net/fuxuemingzhu/article/details/82716042
# IDEA : BINARY SEARCH
# python 3
class Solution:
def minEatingSpeed(self, piles, H):
minSpeed, maxSpeed = 1, max(piles)
while minSpeed <= maxSpeed:
speed = minSpeed + (maxSpeed - minSpeed) // 2
hour = 0
for pile in piles:
hour += math.ceil(pile / speed)
if hour <= H:
maxSpeed = speed - 1
else:
minSpeed = speed + 1
return minSpeed
# V1''''
# https://blog.csdn.net/fuxuemingzhu/article/details/82716042
# IDEA : BINARY SEARCH
class Solution(object):
def minEatingSpeed(self, piles, H):
"""
:type piles: List[int]
:type H: int
:rtype: int
"""
l, r = 1, sum(piles)
# [l, r)
while l < r:
K = l + (r - l) / 2
curH = 0
for p in piles:
curH += p // K + (1 if p % K else 0)
if curH > H:
l = K + 1
else:
r = K
return l
# V2
# Time: O(nlogr)
# Space: O(1)
class Solution(object):
def minEatingSpeed(self, piles, H):
"""
:type piles: List[int]
:type H: int
:rtype: int
"""
def possible(piles, H, K):
return sum((pile-1)//K+1 for pile in piles) <= H
left, right = 1, max(piles)
while left <= right:
mid = left + (right-left)//2
if possible(piles, H, mid):
right = mid-1
else:
left = mid+1
return left