0033_search-in-rotated-sorted-array【M】(pivot 有序数组(值不重复)的二分查找)

  • JY:pivot 有序数组(值不重复)的二分查找

1、二分查找

  • 如果是一个普通升序数组,只需要mid值与target之间的简单判断:
    • 如果nums[mid] == target,则直接返回mid
    • 如果nums[mid] < target,则targetmid的后半部分,low = mid+1
    • 如果nums[mid] > target,则targetmid的前半部分,high = mid-1
  • 旋转升序数组从任意位置劈开后,至少有一半是有序的,因此可以先找到有序的一段,然后看target在不在这一段里,如果在,就把另一半丢弃;如果不在,就把这一段丢弃。
  • 先判断nums[mid]nums[high]的大小,以确定哪一半是升序区间,并判断target是否在该区间中,从而进一步判断是更新low还是high
    • 如果nums[mid] == target,则直接返回mid
    • 如果nums[mid] < nums[high],表明后半部分严格升序,此时判断target是否位于后半部分区间即可更新lowhigh
    • 如果nums[mid] > nums[high],表明前半部分严格升序;此时判断target是否位于前半部分区间即可更新lowhigh
    • 如果nums[mid] == nums[high](只有当有序pivot数组中允许数值重复才有可能出现该情况)
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        low, high = 0, len(nums) - 1
        while low <= high:
            mid = low + (high - low) // 2
            # jy: 如果 mid 值即为目标值, 直接返回
            if nums[mid] == target:
                return mid

            if nums[mid] < nums[high]:
                # jy: 当 target == nums[high] 时也更新 low, 使得不会错过正确值
                if nums[mid] < target <= nums[high]:
                    low = mid + 1
                else:
                    high = mid - 1
            elif nums[mid] > nums[high]:
                if nums[low] <= target < nums[mid]:
                    high = mid - 1
                else:
                    low = mid + 1
            # jy: 只有当有序 pivot 数组中允许数值重复才有可能出
            #     现 nums[mid] == nums[high] 的情况 (如 0081)
            else:
                #high -= 1
                high = mid - 1
        return -1


nums = [4, 5, 6, 7, 0, 1, 2]
target = 0
res = Solution().search(nums, target)
print(nums, " === ", target, " === ", res)


target = 3
res = Solution().search(nums, target)
print(nums, " === ", target, " === ", res)


nums = [3, 4, 5, 6, 7, 0, 1, 2]
target = 4
res = Solution().search(nums, target)
print(nums, " === ", target, " === ", res)

2、改写解法 1

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        pass
  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

融码一生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值