Given N piles of bananas, the ith pile has piles[i] bananas and H hours time until guards return (N <= H). Find the minimum (S) bananas to eat per hour such that Koko can eat all the bananas within H hours. Each hour, Koko chooses some pile of bananas and eats S bananas from that pile. If the pile has less than S bananas, then she consumes all of them, and wont eat any more bananas during that hour. 
Example 1:
Input:
n = 4
piles = [3, 6, 7, 11]
H = 8
Output:
4
Example 2:
Input:
n = 5
piles = [30, 11, 23, 4, 20]
H = 5
Output:
30
Your Task:
You don't need to read input or print anything. Your task is to complete the function Solve() which takes an integer n and a list of piles and integer H denoting Hour and return the minimum bananas to eat per hour.
Constraint:
1 <= n <= 10^{4 }
1 <= piles[i] <= 10^{9 }
n <= H <= 10^{4}

Difficulty: MEDIUM

Starter code:
#User function Template for python3



class Solution:

    def Solve(self, N, piles, H):

        # Code here

Solutions:
class Solution:

	def Solve(self, N, piles, H):
		(low, high) = (1, max(piles) + 1)
		while low < high:
			mid = (low + high) // 2
			count = 0
			for p in piles:
				count += (p + mid - 1) // mid
			if count > H:
				low = mid + 1
			else:
				high = mid
		return low


class Solution:

	def Solve(self, N, piles, H):
		import math
		l = 1
		r = max(piles)
		while l <= r:
			mid = (l + r) // 2
			count = 0
			for i in range(N):
				count = count + math.ceil(piles[i] / mid)
			if count <= H:
				ans = mid
				r = mid - 1
			else:
				l = mid + 1
		return ans


class Solution:

	def ok(self, m, n, p, h):
		days = 0
		for i in range(n):
			days += (p[i] + m - 1) // m
		return days <= h

	def Solve(self, N, piles, H):
		(lo, hi) = (1, int(1000000000.0))
		ans = 0
		while lo <= hi:
			mi = (lo + hi) // 2
			if self.ok(mi, N, piles, H):
				ans = mi
				hi = mi - 1
			else:
				lo = mi + 1
		return ans


import math

class Solution:

	def Solve(self, N, piles, H):
		(l, r) = (0, max(piles))
		res = max(piles)
		while l <= r:
			mid = (l + r) // 2
			total = 0
			for p in piles:
				total += math.ceil(p / mid)
			if total <= H:
				res = min(res, mid)
				r = mid - 1
			else:
				l = mid + 1
		return res


import math

class Solution:

	def Solve(self, n, piles, h):
		l = 1
		r = max(piles)
		mid = (l + r) // 2
		ans = 999999999999
		while l <= r:
			mid = l + (r - l) // 2
			g = 0
			for i in range(n):
				g += math.ceil(piles[i] / mid)
			if g <= h and mid < ans:
				ans = mid
				r = mid - 1
			elif g <= h:
				r = mid - 1
			elif g > h:
				l = mid + 1
		return l


import math

class Solution(object):

	def Solve(self, N, piles, H):

		def maxPile():
			maxPile = float('-inf')
			for pile in piles:
				if pile > maxPile:
					maxPile = pile
			return maxPile

		def canEatAllPiles(k, H):
			hours = 0
			for pile in piles:
				hours += math.ceil(pile / k)
			return hours <= H
		(left, right) = (1, maxPile())
		while left <= right:
			k = (left + right) // 2
			if canEatAllPiles(k, H):
				right = k - 1
			else:
				left = k + 1
		return left


import math

class Solution:

	def Solve(self, N, piles, H):
		low = 1
		high = max(piles)
		res = 0
		while low <= high:
			mid = low + (high - low) // 2
			hours = 0
			for pile in piles:
				hours += math.ceil(pile / mid)
			if hours <= H:
				res = mid
				high = mid - 1
			else:
				low = mid + 1
		return res


import math

class Solution:

	def eattime(self, piles, capacity):
		time = 0
		for ele in piles:
			time += math.ceil(ele / capacity)
		return int(time)

	def Solve(self, N, piles, H):
		(low, high) = (1, max(piles))
		mins = float('inf')
		while low <= high:
			mid = (low + high) // 2
			time = self.eattime(piles, mid)
			if time <= H:
				mins = min(mins, mid)
				high = mid - 1
			else:
				low = mid + 1
		return mins


import math

class Solution:

	def Solve(self, N, piles, H):
		l = 1
		r = max(piles)
		result = r
		while l <= r:
			k = (l + r) // 2
			hours = 0
			for pile in piles:
				hours += math.ceil(pile / k)
			if hours <= H:
				result = min(result, k)
				r = k - 1
			else:
				l = k + 1
		return result


class Solution:

	def Solve(self, n, piles, h):
		low = 1
		high = max(piles) + 1
		ans = float('inf')
		while low <= high:
			mid = low + high >> 1
			hours = 0
			for pile in piles:
				if pile % mid == 0:
					hours += pile // mid
				else:
					hours += pile // mid + 1
			if hours > h:
				low = mid + 1
			else:
				ans = min(ans, mid)
				high = mid - 1
		return ans


class Solution:

	def Solve(self, N, piles, H):
		lo = 1
		hi = max(piles)

		def caneat(mid):
			t = 0
			for i in range(N):
				t += piles[i] // mid + (1 if piles[i] % mid else 0)
			if t > H:
				return False
			return True
		while lo <= hi:
			mid = (lo + hi) // 2
			if caneat(mid):
				hi = mid - 1
			else:
				lo = mid + 1
		return lo


import math

class Solution:

	def getHours(self, N, piles, mid):
		if mid == 0:
			return float('inf')
		else:
			h = 0
			for i in range(N):
				if mid >= piles[i]:
					h += 1
				else:
					h += int(math.ceil(piles[i] / mid))
			return h

	def Solve(self, N, piles, H):
		if H == N:
			return max(piles)
		else:
			(l, r, mid) = (0, max(piles), 0)
			min_banana = r
			while l <= r:
				mid = (l + r) // 2
				H1 = self.getHours(N, piles, mid)
				if H1 <= H:
					min_banana = min(min_banana, mid)
					r = mid - 1
				elif H1 > H:
					l = mid + 1
			return min_banana


class Solution:

	def Solve(self, N, piles, H):
		low = 0
		high = max(piles)
		while low <= high:
			mid = (low + high) // 2
			hours = sum(((n - 1) // mid + 1 for n in piles))
			if hours <= H:
				high = mid - 1
			else:
				low = mid + 1
		return low


import math

class Solution:

	def find_time(self, piles, H, N, mid):
		temp = 0
		for i in range(N):
			temp += math.ceil(piles[i] / mid)
			if temp > H:
				break
		return temp

	def Solve(self, N, piles, H):
		low = 1
		high = max(piles)
		ans = float('inf')
		while low <= high:
			mid = (low + high) // 2
			time = self.find_time(piles, H, N, mid)
			if time == H:
				ans = min(ans, mid)
				high = mid - 1
			elif time > H:
				low = mid + 1
			else:
				ans = min(ans, mid)
				high = mid - 1
		return ans


import math as m

class Solution:

	def Solve(self, N, piles, H):
		l = 1
		r = max(piles)
		s = sum(piles)
		while l <= r:
			mid = (l + r) // 2
			ans = 0
			for i in piles:
				ans += m.ceil(i / mid)
			if ans <= H:
				r = mid - 1
			else:
				l = mid + 1
		return l


import math

class Solution:

	def Solve(self, N, piles, H):
		(low, high) = (1, max(piles))

		def isPossible(cap):
			time = 0
			for i in piles:
				time += math.ceil(i / cap)
			return time <= H
		while low < high:
			mid = (low + high) // 2
			if isPossible(mid):
				high = mid
			else:
				low = mid + 1
		return low


import math

class Solution:

	def Solve(self, N, piles, H):
		(low, high) = (1, max(piles))
		res = high

		def eatAll(speed):
			time = 0
			for i in range(N):
				time += math.ceil(piles[i] / speed)
			return time
		while low <= high:
			mid = (low + high) // 2
			time = eatAll(mid)
			if time <= H:
				res = min(res, mid)
				high = mid - 1
			else:
				low = mid + 1
		return res


from math import ceil

class Solution:

	def Solve(self, N, piles, H):

		def hours_required(k):
			h = 0
			for p in piles:
				h += ceil(p / k)
			return h
		low = 1
		high = max(piles)
		while low <= high:
			mid = (low + high) // 2
			if hours_required(mid) <= H:
				high = mid - 1
			else:
				low = mid + 1
		return low


import math

class Solution:

	def Solve(self, N, piles, h):

		def eatingTimeWithSpeed(piles, speed):
			return sum((math.ceil(p / speed) for p in piles))
		l = math.ceil(sum(piles) / h)
		r = max(piles)
		while l <= r:
			m = (l + r) // 2
			if eatingTimeWithSpeed(piles, m) > h:
				l = m + 1
			else:
				r = m - 1
		return l


import math

class Solution:

	def Solve(self, N, piles, hrs):

		def checkTime(piles, time):
			c = 0
			for i in piles:
				c += math.ceil(i / time)
			return c
		l = 0
		h = max(piles)
		while l <= h:
			mid = (l + h) // 2
			target = checkTime(piles, mid)
			if target <= hrs:
				h = mid - 1
			else:
				l = mid + 1
		return l


class Solution:

	def Solve(self, N, piles, H):
		if N == H:
			x = max(piles)
			return x
		else:
			left = 1
			right = max(piles)
			while left < right:
				mid = (left + right) // 2
				hours = sum(((p + mid - 1) // mid for p in piles))
				if hours > H:
					left = mid + 1
				else:
					right = mid
			return left


import math

class Solution:

	def Solve(self, N, piles, H):
		left = 1
		right = max(piles)
		ans = 0
		while left <= right:
			mid = (left + right) // 2
			hours = 0
			for i in range(len(piles)):
				hours += math.ceil(piles[i] / mid)
			if hours <= H:
				ans = mid
				right = mid - 1
			else:
				left = mid + 1
		return ans


class Solution:

	def Solve(self, N, piles, H):
		ans = max(piles)
		low = 1
		high = ans
		while low <= high:
			mid = (low + high) // 2
			count = 0
			total = 0
			for i in range(len(piles)):
				count += 1
				if piles[i] >= mid:
					count += piles[i] // mid
					if piles[i] % mid == 0:
						count -= 1
			if count <= H:
				ans = min(ans, mid)
				high = mid - 1
			else:
				low = mid + 1
		return ans


class Solution:

	def Solve(self, N, piles, h):
		left = 1
		right = max(piles)

		def can_eat_all_bananas(speed):
			time = 0
			for pile in piles:
				time += (pile + speed - 1) // speed
			return time <= h
		while left < right:
			mid = (left + right) // 2
			if can_eat_all_bananas(mid):
				right = mid
			else:
				left = mid + 1
		return left


class Solution:

	def Solve(self, N, piles, H) -> int:
		(low, high) = (1, 1000000000)
		while low < high:
			mid = low + (high - low) // 2
			total = sum(((p + mid - 1) // mid for p in piles))
			if total > H:
				low = mid + 1
			else:
				high = mid
		return low


class Solution:

	def Solve(self, N, piles, H):

		def feasible(speed) -> bool:
			return sum(((pile - 1) // speed + 1 for pile in piles)) <= H
		(l, r) = (1, max(piles))
		while l < r:
			mid = l + (r - l) // 2
			if feasible(mid):
				r = mid
			else:
				l = mid + 1
		return l


class Solution:

	def Solve(self, N, piles, h):
		i = 1
		j = 10 ** 9
		ans = 10 ** 15
		while i <= j:
			m = (i + j) // 2
			hr = 0
			for el in piles:
				if el <= m:
					hr += 1
				else:
					c = el // m
					if el % m != 0:
						hr += 1
					hr += c
			if hr <= h:
				ans = min(m, ans)
			if hr <= h:
				j = m - 1
			elif hr > h:
				i = m + 1
			else:
				break
		return ans


from math import ceil

class Solution:

	def Solve(self, N, piles, H):
		(left, right) = (1, max(piles))
		res = right
		while left <= right:
			mid = (left + right) // 2
			hours = 0
			for p in piles:
				hours += ceil(p / mid)
			if hours <= H:
				res = min(res, mid)
				right = mid - 1
			else:
				left = mid + 1
		return res


class Solution:

	def Solve(self, N, piles, H):
		l = 1
		r = max(piles)

		def eat(speed, h):
			time = 0
			for i in piles:
				time += (i + speed - 1) // speed
			return time <= h
		while l < r:
			mid = (l + r) // 2
			if eat(mid, H):
				r = mid
			else:
				l = mid + 1
		return l


import math

class Solution:

	def Solve(self, N, piles, H):
		if N == H:
			return max(piles)
		s = 1
		e = ans = max(piles)
		key = 1
		while s <= e:
			count = 0
			m = (s + e) // 2
			for i in piles:
				count += math.ceil(i / m)
			if count == H:
				ans = min(ans, m)
				e = m - 1
			elif count < H:
				ans = min(ans, m)
				e = m - 1
			else:
				s = m + 1
		return ans


class Solution:

	def Solve(self, N, piles, h):
		left = 0
		right = max(piles)
		ans = float('inf')
		while left <= right:
			mid = (left + right) // 2
			hrs = 0
			for i in piles:
				hrs += (i + mid - 1) // mid
			if hrs <= h:
				ans = min(ans, mid)
				right = mid - 1
			else:
				left = mid + 1
		return ans


import math

class Solution:

	def Solve(self, N, piles, h):
		l = 1
		r = 10 ** 9
		while l < r:
			mid = (l + r) // 2
			if self.isPossible(piles, mid, h):
				r = mid
			else:
				l = mid + 1
		return l

	def isPossible(self, piles, k, h):
		hrs = 0
		for x in piles:
			hrs += math.ceil(x / k)
		return hrs <= h


import math

class Solution:

	def can_eat_all_bananas(self, piles, num, H):
		idx = 0
		cnt = 0
		for pile in piles:
			H -= pile // num
			if pile % num:
				H -= 1
			if H < 0:
				return False
		return True

	def Solve(self, N, piles, H):
		low = 1
		high = max(piles)
		min_bananas = math.inf
		while low <= high:
			mid = (low + high) // 2
			if self.can_eat_all_bananas(piles[:], mid, H):
				min_bananas = min(min_bananas, mid)
				high = mid - 1
			else:
				low = mid + 1
		return min_bananas


class Solution:

	def canEatInTime(self, piles, k, h):
		hrs = 0
		for pile in piles:
			if pile % k != 0:
				hrs += 1
			div = pile // k
			hrs += div
		return hrs

	def Solve(self, n, piles, h):
		(low, high) = (1, max(piles))
		while low <= high:
			mid = low + (high - low) // 2
			total_hr = self.canEatInTime(piles, mid, h)
			if total_hr <= h:
				high = mid - 1
			else:
				low = mid + 1
		return low


class Solution:

	def Solve(self, N, piles, H):
		l = 1
		r = max(piles)

		def eatHours(m):
			return sum(((pile - 1) // m + 1 for pile in piles))
		while l < r:
			m = (l + r) // 2
			if eatHours(m) <= H:
				r = m
			else:
				l = m + 1
		return l


class Solution:

	def Solve(self, N, piles, H):

		def fn(each):
			hrs = 0
			for val in piles:
				hrs += (val + each - 1) // each
				if hrs > H:
					return False
			return True
		(l, r) = (1, max(piles))
		while l <= r:
			mid = l + r >> 1
			if fn(mid) == False:
				l = mid + 1
			else:
				r = mid - 1
		return l


from math import ceil

class Solution:

	def Solve(self, N, piles, H):
		(l, r) = (1, max(piles))
		res = r
		while l <= r:
			s = (l + r) // 2
			hours = 0
			for e in piles:
				hours += ceil(e / s)
			if hours > H:
				l = s + 1
			else:
				res = min(res, s)
				r = s - 1
		return res


class Solution:

	def canEatInTime(self, arr, k, H):
		hours = 0
		for ele in arr:
			div = ele // k
			hours += div
			if ele % k != 0:
				hours += 1
		return hours <= H

	def Solve(self, N, piles, H):
		low = 1
		high = 10 ** 9
		while low <= high:
			mid = low + (high - low) // 2
			if self.canEatInTime(piles, mid, H):
				high = mid - 1
			else:
				low = mid + 1
		return low


import math

class Solution:

	def Solve(self, n, piles, h):
		start = 1
		end = max(piles)
		ans = -1
		while start <= end:
			mid = (start + end) // 2
			hour_spent = 0
			for pile in piles:
				hour_spent += math.ceil(pile / mid)
			if hour_spent <= h:
				end = mid - 1
				ans = mid
			else:
				start = mid + 1
		return ans


import math

class Solution:

	def Solve(self, N, piles, H):
		i = 1
		j = max(piles)
		while i < j:
			mid = i + j >> 1
			hrs = 0
			for p in piles:
				if p <= mid:
					hrs = hrs + 1
				else:
					hrs = hrs + math.ceil(p / mid)
			if hrs <= H:
				j = mid
			else:
				i = mid + 1
		return i