题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
思路要点:
1、二分法找到“断崖点”
2、判断tatget属于左边还是右边,在其中一边使用二分搜索
代码:
import math
from bisect import bisect_left
class Solution:
def __init__(self,lst,target):
self.nums=lst
self.target=target
self.result=self.search(self.nums,self.target)
def search(self,nums,target):
left=0
right=len(nums)-1
while left<=right:
mid=math.ceil((left+right)/2)
if mid==0 or mid==len(nums)-1 or (nums[mid]<nums[mid+1] and nums[mid]<nums[mid-1]) :
break
if nums[mid]>nums[len(nums)-1]: #说明断崖点在右边
left=mid+1
continue
if nums[mid]<nums[0]: #说明断崖点在左边
right=mid-1
continue
steep=mid
if target<nums[0]:
lst=nums[steep:]
index=bisect_left(lst, target)
if index==len(lst):
return -1
return index+len(nums)-len(lst)
else:
lst=nums[:steep]
index=bisect_left(lst, target)
if index==len(lst):
return -1
return index
'''
left 0 4 4
right 6 6 4
mid 3 5 4
'''
if __name__=='__main__':
nums=[3,4,5,6,7,0,1,2]
target=1
print('数组:\n')
print(nums)
print('\n')
print('target:'+str(target))
solution=Solution(nums,target)
index=solution.result
print('index='+str(index))
运行结果:
数组:
[3, 4, 5, 6, 7, 0, 1, 2]
target:1
index=6
数组:
[3, 4, 5, 6, 7, 0, 1, 2]
target:9
index=-1