题目描述
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
思路
两次二分查找,第一次二分查找找最小值(即分割点),第二次二分查找即在有序数组中找目标值
第一次二分查找:
- 因为是旋转排序数组,我们拿中间的值与最右边的值比较:
- 如果比他大,则说明最小值在mid后面
- 如果比他小,则说明最小值在mid前面
第二次二分查找:
- 目标值与最右边的值比较(看目标值在前后有序数组的哪个),
- 相等则返回最右边索引
- 比右边的值大,则说明在前一个有序数组 ,
- 反之,则在后一个有序数组中。
- 利用二分查找即可
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums)<=0:
return -1
l=0
r=len(nums)-1
while l<r:
mid=l+(r-l)/2
if nums[mid]>nums[r]:
l=mid+1
else:
r=mid
t=l
l=0
r=len(nums)-1
if target==nums[r]:
return r
elif target>nums[r]:
r=t-1
else:
l=t
while l<r:
mid=l+(r-l)/2
if target>nums[mid]:
l=mid+1
else:
r=mid
return l if nums[l]==target else -1
Ps:推荐一个二分查找的模板 https://www.liwei.party/2019/06/17/leetcode-solution-new/search-insert-position/
确实不用再担心输出left还是right了,同时循环内部就两个分支,也加快了速度