参考自“代码随想录”
lc.35搜索插入位置
如果查找到,直接返回mid
如果没查找到,最后的区间长度要么是1,要么是2
如果区间是1,left == right == mid
此时两种情况都是插入到left的位置
如果区间是2,left == mid
此时两种情况也是插入到left的位置
所以如果没查找到,返回left
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left - right) // 2 + right
if target < nums[mid]:
right = mid - 1
elif target > nums[mid]:
left = mid + 1
else:
return mid
return left
lc.34在排序数组中查找元素的第一个和最后一个下标
还是去二分查找,分别找左、右边界,当查找到时:
如果需要找右边界——修改left向右继续查找
如果需要找左边界——修改right向左继续查找
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def RightBorder(nums, left, right):
border_right = - 1
while left <= right:
mid = (left - right) // 2 + right
if target < nums[mid]:
right = mid - 1
elif target > nums[mid]:
left = mid + 1
else:
border_right = mid
left = mid + 1
return border_right
def LeftBorder(nums, left, right):
border_left = -1
while left <= right:
mid = (left - right) // 2 + right
if target < nums[mid]:
right = mid - 1
elif target > nums[mid]:
left = mid + 1
else:
border_left = mid
right = mid - 1
return border_left
return [LeftBorder(nums, 0, len(nums) - 1), RightBorder(nums, 0, len(nums) - 1)]
lc.69x的平方根
和lc35一样,只是返回right(向下取整,且不存在负数的情况,那就是最低取到0)
class Solution:
def mySqrt(self, x: int) -> int:
left = 0
right = x
while left <= right:
mid = (left - right) // 2 + right
if mid * mid > x:
right = mid - 1
elif mid * mid < x:
left = mid + 1
else:
return mid
return right
lc.367有效的完全平方数
class Solution:
def isPerfectSquare(self, num: int) -> bool:
left = 0
right = num
while left <= right:
mid = (left- right) // 2 + right
if mid * mid > num:
right = mid - 1
elif mid * mid < num:
left = mid + 1
else:
return True
return False
lc153.寻找旋转排序数组中的最小值
无论如何旋转,数组中总有至少一半是有序的!!!
这里采用左闭右闭区间【】
每次考查mid和right的数值关系
如果mid < right,代表mid —— right这个区间是有序递增的,那最小值在left-mid(注意包括mid)
如果mid > right,代表最小值在mid+1 —— right这个区间
如果mid == right,代表此处就是最小值
class Solution:
def findMin(self, nums: List[int]) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = (left - right) // 2 + right
if nums[mid] > nums[right]:
left = mid + 1
elif nums[mid] < nums[right]:
right = mid
else:
return nums[mid]