Leetcode33.旋转排序数组与面试题11.旋转数组的最小数字 Python实现及其详解

在这里插入图片描述
本题要点就是:只在有上升顺序的那一端做二分查找,妥妥的能解决,并且思路清晰,虽然思路很简单,但是二分查找看的是细节,判断语句中使用大于等于,还是大于,或者使用小于等于还是小于,这些写错一个就可能会要了你的命!
代码实现:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
    	n = len(nums)
    	left,right =0,n-1
    	while left<=right:
    		mid = left+(right-left)//2
    		if nums[mid]==target:
    			return mid 
    		elif nums[left]<=nums[mid]:
    			if nums[left]<=target<nums[mid]:
    				right=mid-1
    			else:
    				left = mid+1
    		else:
    			if nums[mid]<taregt<=nums[right]:
    				left = mid+1
    			else:
    				right=mid- 1
    	return -1

自己每个一段时间做这道题的时候经常有以下几个地方会写错,经过这次整理之后希望以后不会写错了

  1. 为什么是 while left <= right:, 在与正常的二分查找模板一样,我们要考虑当left和right相遇时,此时对应的值是否是target,所以不能把这个数给刨除掉
  2. 为什么是 nums[left]<=nums[mid],这里我们考虑一个例子[2,1],target=1,此时对于这种情况,mid=0,如果是nums[left]<nums[mid],那么会进入下一个else,进而right=mid-1,此时,right=-1,return -1,导致第二个值无法被查询,所以这也是当mid==left时,需要判断一下
  3. 为什么是nums[mid]<target<=nums[right] 因为前面判断过,此时 nums[mid]肯定不等于target,如果此时右边是递增的,只需要考虑nums[mid+1]就可以了,所以写成这样也是可以的nums[mid+1]<=target<=nums[right]

在这里插入图片描述
这道题的思路就是:使用mid值和right比较,这一点相当重要了

class Solution:
    def minArray(self, numbers: List[int]) -> int:
    	n = len(numbers)
    	left, right = 0,n-1
    	while left<right:
    		mid = left+(right-left)//2
    		if numbers[mid]<numbers[right]:
    			# 右侧递增,但是mid处可能是最小值
    			right=mid
    		elif numbers[mid]==numbers[right]:
    			# 就算right是最小值,把它过滤掉还有mid呢
    			right-=1
    		else:
    			# 左侧递增,那么mid肯定不是最小值
    			left = mid+1
    	return numbers[left]

同样的列举几个疑问你要是全理解了,估计这道题你就彻底懂了

  1. 为什么while left<right:?很简单,这道题没有target,没有一个明确比较的点,我们只能不断地缩小范围,逼近直到确定这个最小值点,如何确定?那么当然是当left==right的时候了,那么此时需要返回nums[left]或者nums[right]
  2. 为什么numbers[mid]>numbers[right],要right=mid,因为我们只能得到mid的右侧包括mid在内组成的是一个递增数列,然而并不能确定mid处是否是一个最小值,即mid处可能是一个最小值
  3. 为什么要left = mid+1?因为走到这一步可以明确,mid左侧,包括mid处是一个递增数列,那么递增的数列不可能存在最小值,那么可以执行left = mid+1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值