题目描述:
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:
输入:nums = [1], target = 0
输出:-1
来源:力扣(LeetCode)
算法思路:
这个题的方法有两种第一种直接遍历,时间复杂度为O(n) 简单有效,但是数据大的话还是会响应很慢。第二种方法就很好,采用折半查找的思想
1、利用折半查找先将最小值的位置查找出来,作为分解点
2、再对分界点左右两边分别使用折半查找,找到目标数的坐标。
代码实现:
def binary_search(nums,low,high,x):
"""
:param nums: list[int]
:param low: int
:param high: int
:return: int
"""
j=0
while low<=high:
mid = (low + high) // 2
j=j+1
if nums[mid]<x:
low=mid+1
elif nums[mid]>x:
high=mid-1
else:
return mid
if low>high:
return -1
return low
def binary_search_2(nums,low,high):
"""
找到有序数组旋转后的最小值的位置
实例:
输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
:param nums: list[int]
:param low: int
:param high: int
:return: int
"""
i=0
while low<high:
mid=(low+high)//2
i=i+1
if nums[mid]>nums[high]:
low=mid+1
else:
high=mid
print("i",i)
return low
def Search_in_Rotated_Sorted_Array(nums, target):
"""
例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你旋转后的数组nums和一个整数 target ,如果nums中存在这个目标值target ,
则返回它的下标,否则返回 -1 。
:param nums: list[int]
:param target: int
:return: int
"""
high=len(nums)-1
mid=binary_search_2(nums,0,high)
print("mid",mid)
index_1=-1
index_2=-1
if mid>0:
index_1=binary_search(nums,0,mid-1,target)
if index_1>-1:
return index_1
if mid<=high:
index_2=binary_search(nums,mid,high,target)
if index_2>-1:
return index_2
if __name__ == '__main__':
my_list=[2,4,5,6,7,0,1]
target=7
index=Search_in_Rotated_Sorted_Array(my_list,target)
print('index',index)