概念:
二分查找的前提条件是:
1.数组是有序的;2.数组中无重复元素,一旦出现重复元素,则返回的元素下标可能不是唯一的。
边界条件:
在此处有三兄弟left, right, mid,需要搞清楚他们之间的关系
while left <= right: or while left < right?
right = mid - 1 or right = mid
其实上述两种方式都是可行的,这就涉及到了区间概念了,二分法,区间定义一般为两种,左闭又闭[left, right],或者左闭右开[left, right)。
左闭右闭
也即[left, right],定义的target在这个区间里,有如下两点:
1.while left <= right,此处使用的是<=,因为left== right是有意义的
2.if nums[mid] > target ,target落在了区间[left, mid),此处大家看清楚这个区间,是个右开,这个时候right的赋值应该为right = mid - 1,因为nums[mid]一定不是target
左闭右开
也即 [left, right),定义target在这个区间里,有如下两点:
1.while left < right,此处使用的是 < ,因为left == right 在这个区间里是么有意义的
2.if nums[mid] > target,因为当前nums[mid]不等于target,去左区间继续寻找,而寻找区间是左闭右开,所以right 赋值为 right = mid
leetcode题目
下面的题目我们使用左闭右闭区间
代码 python:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if target == nums[mid]:
return mid
elif target > nums[mid]:
left = mid + 1
else:
right = mid - 1
return -1
代码 python:
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if target == nums[mid]:
return mid
elif target > nums[mid]:
left = mid + 1
else:
right = mid - 1
return right + 1
代码 python:
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def binarySearch(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if target == nums[mid]:
return mid
elif target > nums[mid]:
left = mid + 1
else:
right = mid - 1
return -1
index = binarySearch(nums, target)
left, right = index, index
while left - 1 >= 0 and nums[left - 1] == target:
left = left - 1
while right + 1 < len(nums) and nums[right + 1] == target:
right += 1
return [left, right]
代码python:
class Solution:
def mySqrt(self, x: int) -> int:
left = 1
right = x
while left <= right:
mid = (left + right) // 2
if x == mid ** 2:
return mid
elif x >= mid ** 2:
left = mid + 1
else:
right = mid - 1
return right
class Solution:
def isPerfectSquare(self, num: int) -> bool:
left = 1
right = num
while left <= right:
mid = (left + right) // 2
if mid **2 == num:
return True
elif mid **2 > num:
right = mid - 1
else:
left = mid + 1
return False
上面的五道题,后面四道代码中都有第一道的影子。