旋转数组的最小数字(简单)
class Solution:
def minArray(self, numbers: List[int]) -> int:
left,right = 0, len(numbers) - 1
#注意这儿的判断条件是numbers[mid]与numbers[right]
#而不是numbers[mid]与numbers[0]或者numbers[-1]或者numbers[left]做比较
while left < right:
mid = left + (right - left) // 2
if numbers[mid] < numbers[right]:
right = mid
elif numbers[mid] > numbers[right]:
left = mid + 1
else :
#如果相等的话,无法进行下一步判断了
#比如2,2,2,1,2]与【2,1,2,2,2】
#right-1,可缩小范围
right -= 1
return numbers[left]
搜索旋转排序数组(中等)
搜索旋转排序数组 https://leetcode-cn.com/problems/search-in-rotated-sorted-array/
这道题,最直观的想法,是用二分法找到数值最小的数的index,即分水岭,此时左右皆是有序的,然后进行判断,是在做左边还是在右边进行二分查找,查找对应数字,整体复杂度依旧是log(N)
但是更简洁的作答如下:核心是判断哪一半边是升序,哪一半边不是,然后判断数字存在哪一半边,如果是存在于升序的那一边,则直接二分查找,如果不是,则-1缩小非升序那一边的搜索范围
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right = 0,len(nums)-1
while left < right:
mid = left + (right - left)//2
if nums[mid] == target:
return mid
if nums[mid] < nums[left]:
#说明左边不是升序,右边是
if nums[mid] <= target <= nums[right]:
#右边寻找
left = mid + 1
else:
#左边寻找
right -= 1
else:
#说明左边升序,右边不是
if nums[left]<=target<=nums[mid] :
#左边
right = mid
else:
#右边
left += 1
if nums[left] == target:
return left
else:
return -1
剑指 Offer II 072. 求平方根
class Solution:
def mySqrt(self, x: int) -> int:
left = 1
right = x//2 + 1
while left <= right:
mid = left + (right - left)//2
if x / mid < mid:
right = mid - 1
elif x / mid > mid:
if x / (mid + 1) < mid+1:
return mid
else:
left = left + 1
else:
return mid
return 0
74. 搜索二维矩阵(中等)
https://leetcode-cn.com/problems/search-a-2d-matrix/submissions/
方法一:转化为一维数组来做
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
m = len(matrix)
n = len(matrix[0])
left = 0
right = m * n - 1
while left < right:
mid = left + (right - left)//2
#计算对应的横坐标以及纵坐标
x = mid // n
y = mid % n
if matrix[x][y] < target:
left = mid + 1
elif matrix[x][y] > target:
right = mid
elif matrix[x][y] == target:
return True
if matrix[left//n][left%n] == target:
return True
return False
方法二:在行以及列做两次二分查找
在这里插入代码片