704. Binary Search
Problem Description
Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.
You must write an algorithm with O(log n) runtime complexity.
Exceptions
Target is not in the array - this could happen, we need to return -1 if we cannot find it.
Array is empty - return -1
Python Code
The array is sorted and the problem wants a anwser in O(log(n)). It’s straght-forward to think of the binary search.
Recursively Binary Search
def search(self, nums: List[int], target: int) -> int:
return self.binarysearch(nums, 0, len(nums) - 1, target)
def binarysearch(self, nums, start, end, target):
'''
Remember to define a return for recursive binary search
There is not elements means we cannot find target.
If we found target in previous loops, the function should return alreay. So return -1 here.
'''
if start > end:
return -1
'''
These 2 cases can be included in the following if...return.
So no need to treat them as special cases here.
'''
# if start == end and nums[start] != target:
# return -1
# if start == end and nums[start] == target:
# return start
mid = (start + end)//2
if nums[mid] == target:
return mid
if nums[mid] < target:
return self.binarysearch(nums, mid + 1, end, target)
return self.binarysearch(nums, start, mid - 1, target)
Binary Search in While Loop - a template with no infinite loop for sure
def search(self, nums: List[int], target: int) -> int:
'''
corner case
'''
if not nums:
return -1
left, right = 0, len(nums) - 1
'''
use left < right - 1 to avoid infinite loop.
the number of elements reduced from n to 2 after while loop.
we only need to compare if left or right is the value we want.
'''
while left < right - 1:
mid = (left + right) // 2
'''
compare mid >, = or < target separately first
see if we can combine any 2 of them after list out all the senarios
no need to set left or right as mid - 1 or mid + 1
avoid index out of range
'''
if nums[mid] == target:
return mid
if nums[mid] > target:
right = mid
else:
left = mid
'''
after the loop, left and right are next to each other.
remember to see if they are the values we want.
if we want the first target value: check left first
other wise check right first
'''
if nums[left] == target:
return left
if nums[right] == target:
return right
'''
if none of the above clause are returned, return -1
'''
return -1