leetcode专题训练 81. Search in Rotated Sorted Array II

这道题是33. Search in Rotated Sorted Array的升级版,与之前不同的地方是这道题允许存在重复的数字。在之前的33题题解中,我采用的是先找pivot的方法,也就是先找到数组中最大的元素,这样的话,最大的元素两侧都是有序数组,再分别在这两边进行二分查找即可。
然而在这道题中,参考了题解的方法,不用先找pivot。二分归到底就是要知道接下来要去左半边找还是去右半边找,题解中判断的方式就很巧妙。

  1. 首先得到mid,也就是数组的中间位置。
  2. 如果中间位置的左边有序,那么就可以通过判断nums[left] <= target and nums[mid] >= target来判断target是否在左边,如果不在左边,那就在右边。
  3. 如果中间位置的右边有序,那么就可以通过判断nums[mid] <= target and nums[right] >= target来判断target是否在右边,如果不在右边,那就在左边。
  4. 知道是在左边还是右边之后,就可以接着二分了。
然而由于有重复元素,所以可能没法通过nums[left] <= nums[mid]来判断左边是否有序,因为可能会出现1 2 1 1 1这种情况。所以要对nums[left] == nums[mid]的情况进行特殊判断,这时候可以直接使得left++,因为最左边的元素和mid处元素相同,所以这个操作并不会影响最终的结果,而且如果一直弹出最左的和nums[mid]相同的元素,那么一定会使得数组的nums[left]nums[mid]不同,就可以判断左边是否有序了,或者直接就在弹出的过程中找到了target。
class Solution:
    def solve(self, nums: List[int], left: int, right: int, target: int):
        while left <= right:
            mid = (left+right)>>1
            # print(left, right, mid)
            if nums[mid] == target:
                return True
            if nums[mid] == nums[left]:
                left += 1
                continue

            if nums[left] <= nums[mid]:
                if nums[left] <= target and nums[mid] >= target:
                    right = mid-1
                else:
                    left = mid+1
            else:
                if nums[mid] <= target and nums[right] >= target:
                    left = mid+1
                else:
                    right = mid-1
        
        return False

    def search(self, nums: List[int], target: int) -> bool:
        if not nums:
            return False

        l = len(nums)
        return self.solve(nums, 0, l-1, target)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值