Post

LC 875 - Koko Eating Bananas

LC 875 - Koko Eating Bananas

Question

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:

1
2
Input: piles = [3,6,7,11], h = 8
Output: 4

Example 2:

1
2
Input: piles = [30,11,23,4,20], h = 5
Output: 30

Example 3:

1
2
Input: piles = [30,11,23,4,20], h = 6
Output: 23

Constraints:

  • 1 <= piles.length <= 104
  • piles.length <= h <= 109
  • 1 <= piles[i] <= 109

Question here and solution here

Solution

concept

We will use binary search but the search space is from [1,...max(piles)]. Essentially we want to find which number is the minimum that can eat all the piles given time h. The maximum is going to be max(piles) since this will allow Koko to finish all the piles in len(piles).

code

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
class Solution:
	"""
	binary search
	note that the condition is l <= r
	"""
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        
        def can_finish(rate):
            time = 0
            for p in piles:
                time += math.ceil(p/rate)
            return True if time <= h else False

        l, r = 1, max(piles)
        ans = r
        while l <= r:
            mid = (l + r)//2
            if can_finish(mid):
                ans = min(ans, mid)
                r = mid - 1
            else:
                l = mid + 1

        return ans
        
class Solution:
	"""
	notice the l < r
	"""
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        
        def can_finish(rate):
            time = 0
            for p in piles:
                time += math.ceil(p/rate)
            return True if time <= h else False

        l, r = 1, max(piles)
        while l < r:
            mid = (l + r) // 2
            if can_finish(mid):
                r = mid
            else:
                l = mid + 1
        return l

Complexity

time: $O(n\log m)$ where $m$ is the max of piles and n is the len(piles)
space: $O(1)$

This post is licensed under CC BY 4.0 by the author.