每天一道leetcode 搜索旋转排序数组(二分法)

搜索旋转排序数组

33. 搜索旋转排序数组

难度中等651收藏分享切换为英文关注反馈

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:

输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

答:

def search(nums, target):
    left,right=0,len(nums)-1
    while left<=right:
        mid=(left+right)//2
        if target==nums[mid]:
            return mid
        #左侧区间 [left,mid]「连续递增」
        if nums[0]<=nums[mid]:
            if nums[0]<=target<nums[mid]:
                right=mid-1
            else:
                left=mid+1
        #右侧区间 [mid,right]「连续递增」
        else:
            if nums[mid]<target<=nums[len(nums)-1]:
                left=mid+1
            else:
                right=mid-1
    return -1

解析做法:

看到复杂度为O(logn),应该是二分查找,二分查找的过程就是不断收缩左右边界,这道题就是在二分查找的基础上改进,增加判断连续区域部分

  • 普通二分法:

若 target == nums[mid],直接返回
若 target < nums[mid],则 target 位于左侧区间 [left,mid) 中。令 right = mid-1,在左侧区间查找
若 target > nums[mid],则 target 位于右侧区间 (mid,right] 中。令 left = mid+1,在右侧区间查找

  • 根据旋转数组的特性,当元素不重复时,如果 nums[i] <= nums[j],说明区间 [i,j] 是「连续递增」的。

i、j 可以重合,因此,在旋转排序数组中查找一个特定元素时:

若 target == nums[mid],直接返回
若 nums[left] <= nums[mid],说明左侧区间 [left,mid]「连续递增」。此时:
若 nums[left] <= target <= nums[mid],说明 target 位于左侧。令 right = mid-1,在左侧区间查找
否则,令 left = mid+1,在右侧区间查找
否则,说明右侧区间 [mid,right]「连续递增」。此时:
若 nums[mid] <= target <= nums[right],说明 target 位于右侧区间。令 left = mid+1,在右侧区间查找
否则,令 right = mid-1,在左侧区间查找

与nums[0]比较判断是都连续,哪部分连续

原文地址:https://www.cnblogs.com/rower/p/12786005.html