每日一题20201126*(33. 搜索旋转排序数组)

33. 搜索旋转排序数组

image-20201202152424398

思路

  • 二分法

    先对着代码进行讲解。

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # low和high分别指向数组2端
        low, high = 0, len(nums)-1
        while low <= high:
            mid = (low+high) // 2
            # 如果nums[mid]与目标相等,直接return,这里没有异议
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                # 这里开始出现分歧,虽然中位数大于了目标,由于存在
                # 旋转的可能,如果低位也大于目标且低位到中位是递增的
                # 那么可以肯定左半段没有等于target的数了,所以往右侧找
                if nums[low] > target and nums[low] <= nums[mid]:
                    low = mid+1
                # 否则与正常二分保持一致
                else:
                    high = mid-1
            else:
                # 同上
                if nums[high] < target and nums[high] >= nums[mid]:
                    high = mid - 1
                else:
                    low = mid + 1
        return -1

虽然这个数组是被旋转了,但是也满足二分搜索条件,只不过需要做一定的转换。

我们来看下面这个例子: [5, 1, 3] 当目标元素是5的时候,首先二分会找到1,按照以往的数组,这时候low应该等于mid+1,但在这里不一样,因为数组有可能已经被旋转了。

所以需要往左侧走,high = mid-1,当然这个也是有条件的,那就是此时nums[high]也比target小,并且nums[high]要保证大于nums[mid],也就是说后半段要是递增的,那就肯定没有数字比target大了,这时候才会去左边查找。

同理当target比nums[mid]小的时候也是一样。

image-20201202153406536

里面还是有许多坑的,比如递增的条件一定要≥,否则有部分用例会发现你的bug。

大家写完之后可以多写点特殊场景的用例自测一下再提交,通过的概率会大很多!
posted @ 2020-12-02 15:36  米洛丶  阅读(57)  评论(0编辑  收藏  举报