binary search
binary search type 1
searching for an element, single index
- comparision of elements is determined by only condition
l = 0
r = len(nums) - 1
while l <= r:
m = (l + r)//2
if nums[m] == target:
return m
elif nums[m] < target:
l = m + 1
else:
r = m - 1
return l # or -1
binary search type 2
requried to access the current index and its neighbor’s index at the end of the code, there could be one element not handled.
l = 0
r = len(nums)
while l < r:
m = (l + r)//2
if nums[m] == target:
return m
elif nums[m] > target:
r = m
else:
l = m + 1
if l != len(nums) and nums[l] == target:
return l
return -1
binary search type 3
accessing the current index and its left and right indices
l = 0
r = len(nums) - 1
while l + 1 < r:
m = (l + r)//2
if nums[m] == target:
return m
elif nums[m] > target:
r = m
else:
l = m
if nums[l] == target:
return l
if nums[r] == target:
return r
return -1
application for the type 3
-
- Find First and Last Position of Element in Sorted Array
def searchRange(self, nums, target): def _search(nums, target, left): l = 0 r = len(nums) while l < r: m = (l + r)//2 if nums[m] > target or (left and nums[m] == target): r = m else: l = m + 1 return l l_idx = _search(nums, target, True) if l_idx == len(nums) or nums[l_idx] != target: return [-1, -1] return [l_idx, _search(nums, target, False) - 1]
- Find First and Last Position of Element in Sorted Array
but, it’s quite tricky. the following is more understandable
def search(self, nums, val):
l, r = 0, len(nums) - 1
while l <= r:
m = (l + r)//2
if nums[m] == val:
s = e = m
j = m - 1
while j >= 0:
if nums[j] == val:
s = j
j -= 1
j = m + 1
while j <= len(nums) - 1:
if nums[j] == val:
e = j
j += 1
return [s, e]
if nums[m] > val:
r = m - 1
else:
l = m + 1
return [-1, -1]
def searchRange(self, nums, target):
if not nums:
return [-1, -1]
return self.search(nums, target)