选题-LeetCode 33:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1
。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
解题思路:
1、 采用的是迭代的算法,每次迭代都将搜索的区间二分并判断条件。
2、在每次迭代开始,取区间起点、终点和中间的点,先判断该区间是否是单调区间。
3、若该区间是单调区间(起点的值小于中间,中间的值小于终点的值),则按照对普通单调区间进行二分搜索的方法搜索该区间
4、若不为单调区间(即区间在某个点旋转了),则分情况讨论
1)当中间值大于起点值,则表明中间值与起点值在同一个单调区间:
a) 当中间值小于目标值,则搜索区间后半部分
b) 当目标值小于中间值,但大于起点值,则搜索区间的前半部分
c) 其他情况则搜索区间后半部分
2)当中间值小于尾部值时,则表明中间值和尾部值在同一个单调区间:
a) 当中间值大于目标值时,则搜索区间前半部分
b) 当中间值小于目标值,但终点值大于目标值,则搜索区间的后半部分
c) 其余情况则搜索区间的前半部分
5、迭代至区间只剩下小于三个值,再判断剩余区间中的值与目标值是否相同,得出结论
代码:
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
class Solution:
def search(self, nums, target):
end=len(nums)-1
begin=0
while(end>begin+1):
#print(begin,",",end)
temp=(begin+end) // 2
if(nums[begin]<=nums[temp] and nums[temp]<=nums[end]):
if(nums[temp]==target):
return temp
elif(nums[temp]>target and nums[begin]<=target):
end=temp-1
continue
elif(nums[temp]<target and nums[end]>=target):
begin=temp+1
continue
else:
return -1
else:
if(nums[temp]>=nums[begin]):
if(nums[temp]<=target ):
begin=temp
continue
elif(target>=nums[begin]):
end=temp-1
continue
else:
begin=temp+1
continue
elif(nums[temp]<=nums[end]):
if(nums[temp]>=target):
end=temp
continue
elif(target<=nums[end]):
begin=temp+1
continue
else:
end=temp-1
continue
else:
return -1
if(begin==end):
if(nums[begin]==target):
return begin
else:
return -1
elif(begin+1==end and nums[begin]==target):
return begin
elif(begin+1==end and nums[end]==target):
return end
else:
return -1