class Solution: def minEatingSpeed(self, piles: List[int], h: int) -> int: ''' NOTE: Do read the problem carefully! Absolute min speed (k) at which Koko can eat bananas would be 1 and max speed would be max(piles). Of course, these might not be correct and might help Koko finish eating before `h` hours. So, we need to check each k from 1:max(piles) and figure out the min k that lets us consume <= h We can iterate over each k value and check or we can do binary search and figure out least k. ''' start, end = 1, max(piles) k = end while start <= end: mid = (start + end) // 2 total = 0 for p in piles: # If pile has 3 bananas and k = 2, then 3 / 2 = 1.5 # but we don't want fractional values, we will consider # next greatest integer which'd be ceil(p / mid) total += math.ceil(p / mid) # k is valid if total <= h: # Update k if mid is smaller if mid < k: k = mid end = mid - 1 # If mid starts to go bigger than k, then # we can't possibly find any better results # so just break else: break # k is too small 👉 total is large so we need # to move `start` else: start = mid + 1 return k