搜索旋转排序数组
题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
解题思路:
主要是利用二分查找法来解题
因为原始数组是升序数组,所以旋转之后的数组必是两个升序数组的合并
- 首先通过一次二分查找的方式,找到第二个升序数组的第一项
l
,即有序数组的最小一项 - 然后以
l
点,即pol
点作为分割点,利用二分查找法binary_search()
判断target
点在其左右两侧的哪一侧 - 如果返回结果为
-1
,则不在选择的一侧;如果有正确返回,则需要将target
点所在的数组位置加上合适的分割点位置即可,如果在右侧,则需要加上分割点在数组中的索引 a n s + = l e n ( n u m s [ : p o l ] ) ans += len(nums[:pol]) ans+=len(nums[:pol]),如果在左侧则不用
Python源码:
class Solution:
def search(self, nums: 'List[int]', target: 'int') -> 'int':
# 先找到两个第二个升序数组的第一项
l = 0
r = len(nums) - 1
while l < r:
mid = (l+r) // 2
if nums[mid] > nums[r]:
l = mid + 1
else:
r = mid
pol = l
ans = self.binary_search(target, nums[:pol])
if ans== -1:
ans = self.binary_search(target, nums[pol:])
if ans != -1:
ans += len(nums[:pol])
return ans
# 二分查找
def binary_search(self, target, nums):
index = -1
l = 0
r = len(nums) - 1
while l <= r:
mid = (l+r)//2
if nums[mid] < target:
l = mid + 1
elif nums[mid] > target:
r = mid - 1
else:
index = mid
break
return index
欢迎关注我的github:https://github.com/UESTCYangHR