Binary search can reduce the time complexity to O(logN) for sorted items' search. I summarized a framework to slove all the binary search problems under different situation in this post.
1. Framework
1.1. Main Factors
Here are some modifiable main factors for binary search problems.
- Right Boundary: The right boundary of the search range.
len(nums)
orlen(nums)-1
are some commen choices. - Continue Condition: The condition that binary search should continue.
while(left <= right)
orwhile(left < right)
are some commen choices. - Target Found: The action you take when found the target. Depends on specific problem.
- Search One/Other Part: If the target is not found, you wil then search the two divided parts.
left = mid+1
andleft = mid
are 2 examples.
Where nums
is the given list of numbers and target
is the target number.
1.2. Main Framework
The main framework of binary search can be seen as follows:
1 | def binarySearch(nums, target): |
Where nums
is the given list of numbers and target
is the target number.
2. Some Points
Based on different choices of right
, our search interval can be different: If you let right = len(nums)
, then to search over nums
, the index search interval should be [left, right)
; If you let right = len(nums)-1
, then to search over nums
, the index search interval should be [left, right]
. In a word, based on how you set right
, the search interval has two forms: [·,·)
or [·,·]
. Different forms have different settings, choose the suitable one based on specific problems.
2.1. Form One: Search [left, right)
- Right Boundary:
right = len(nums)
- Continue Condition:
while(left < right)
; the loop will stop whenleft == right
, at which time the search interval is[right, right)
, which is an empty interval meaning that the loop should be stopped. - Search One/Other Part: Each step we take a
mid
away, and then the search interval is divided into two parts:[left, mid)
and[mid+1, right)
. To search the first part, we haveright = mid
; To search the latter part, we haveleft = mid+1
.
2.2. Form Two: Search [left, right]
- Right Boundary:
right = len(nums)-1
- Continue Condition:
while(left <= right)
; the loop will stop whenleft == right+1
, at which time the search interval is[right+1, right]
, which is an empty interval meaning that the loop should be stopped. - Search One/Other Part: Each step we take a
mid
away, and then the search interval is divided into two parts:[left, mid-1]
and[mid+1, right]
. To search the first part, we haveright = mid-1
; To search the latter part, we haveleft = mid+1
.
2.3. Notice
When the loop stops, all the items on the left of left
will satisfies the if-else
condition of left = mid+1
;all the items on the right of right
will satisfies the if-else
condition of right = mid
or right = mid-1
.
3. Examples
3.1. Search a number
Given a list of numbers nums
and a number target
, try to find out if target
is in nums
or not. If so, return the index of target
; otherwise, return -1.
1 | def binarySearch(nums, target): |
3.2. Koko Eating Bananas (LeetCode 875)
Koko loves to eat bananas. There are n
piles of bananas, the i-th 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 | Input: piles = [3,6,7,11], h = 8 |
Example 2:
1 | Input: piles = [30,11,23,4,20], h = 5 |
Example 3:
1 | Input: piles = [30,11,23,4,20], h = 6 |
To find the minimum k
, we can binary search k
from 0
to max(piles)
, and check if it satisfies the condition (to finish eating all the bananas before the guards return):
1 | ### Form One: [left, right) |