recently I am playing with binary search algorithm. I prefer the classic template starting with while lo < hi.
This day i met a question, which makes me more confused. The leetcode problem is that given an integer array ribbons, where ribbons[i] represents the length of the i-th ribbon, and an integer k. You may cut any of the ribbons into any number of segments of positive integer lengths, or perform no cuts at all. The goal is to obtain k ribbons of all the same positive integer length. You are allowed to throw away any excess ribbon as a result of cutting. Return the maximum possible positive integer length that you can obtain k ribbons of, or 0 if you cannot obtain k ribbons of the same length. The example input and output is :
Input: ribbons = [7,5,9], k = 4
Output: 4
This code can return the desired result, and it is using higher mid:
class Solution(object):
def maxLength(self, ribbons, k):
s = sum(ribbons)
if s//k == 0:
return 0
lo, hi = 1, s//k
def bs(cut):
return sum([r//cut for r in ribbons]) >= k
while lo < hi:
mid = (lo+hi+1)//2
if bs(mid):
lo = mid
else:
hi = mid-1
return lo
This code can also give the right answer, but use lower mid:
class Solution(object):
def maxLength(self, ribbons, k):
s = sum(ribbons)
if s < k: return 0
def bs(cut):
return sum([r // cut for r in ribbons]) >= k
lo, hi = 1, s//k
while lo <= hi:
mid = (lo+hi) // 2
if bs(mid):
lo = mid + 1
else:
hi = mid - 1
return hi
My question is, how to decide when to use higher or lower mid? In what case should the lo or hi be returned? This really confuses me. Any help is appreciated.