zoukankan      html  css  js  c++  java
  • 每日一题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。
    
    大家写完之后可以多写点特殊场景的用例自测一下再提交,通过的概率会大很多!
  • 相关阅读:
    2018全球最强物联网公司榜单揭晓
    物联网
    kalman滤波
    自动驾驶
    CAN总线基础
    Linux系统下x86和ARM的区别有哪些?
    算法课笔记系列(七)—— 平摊分析Amortized Analysis
    深入理解Linux内存分配
    linux内核--自旋锁的理解
    DMA(直接存储器存取)
  • 原文地址:https://www.cnblogs.com/we8fans/p/14074118.html
Copyright © 2011-2022 走看看