LeetCode Easy: 33. Search in Rotated Sorted Array
一、题目
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
题目大意:给定一个旋转数组和一个 target,返回 target 所在的下标。
二、思路
思路一、因为旋转数组有个点破坏了数组的有序性,但是有且仅有这一个点,此点之前是有序的,此点之后也是有序的,所以可以先找到这个转折点,然后两边就能顺理成章地使用二分法进行搜索了。下边的代码使用的即是此思路。
思路二、如果是正常的排好序的数组,那么使用二分法就能很快地找到 target 所在的下标,但是给定的可能是一个旋转数组,不能直接使用二分法,但是旋转数组虽然不能直接使用二分法,但是其部分数据可以使用,如果我们把旋转数组分成两个部分,那么其中某一部分肯定能使用二分法,剩下的那部分还是一个旋转数组,可以继续二分,可以使用迭代循环或者递归。这是一个思路。
三、代码
#coding:utf-8
class Solution:
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) <= 0:
return -1
pivot = self.FindPivot(nums)
if pivot == -1:
return self.Search(nums,0,len(nums)-1,target)
if nums[pivot] == target:
return pivot
if nums[0] <= target:
return self.Search(nums,0,pivot,target)
else:
return self.Search(nums,pivot+1,len(nums)-1,target)
def Search(self,nums,start,end,target):
if start > end:
return -1
while start <= end:
mid = (start + end)//2
if nums[mid] == target:
print(mid)
return mid
elif nums[mid] > target:
end = mid -1
else:
start = mid + 1
print(-1)
return -1
def FindPivot(self,nums):
start = 0;end = len(nums)-1
if nums[end] > nums[start]: # the list sorted
return -1
# search rotated list
while(start <= end):
mid = (start + end)//2
if nums[mid] > nums[start]: # the Pivot is in [mid,end]
start = mid
elif nums[mid] < nums[start]:
end = mid
else:
return mid
if __name__ == '__main__':
ss = Solution()
nums = [3,1]
ss.search(nums,1)
还有一种更紧凑的代码,博客:https://blog.csdn.net/aliceyangxi1987/article/details/50557496
class Solution:
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
start = 0
end = len(nums) - 1
while start <= end:
mid = (start + end) // 2
if nums[mid] == target:
print(mid)
return mid
if nums[mid] >= nums[start]: # 当nums[mid]属于左边升序序列时
if target >= nums[start] and target < nums[mid]:
end = mid - 1
else:
start = mid + 1
if nums[mid] < nums[end]: # 当nums[mid]属于右边升序序列时
if target > nums[mid] and target <= nums[end]:
start = mid + 1
else:
end = mid - 1
return -1
参考博客:https://blog.csdn.net/sunnyyoona/article/details/18313497
浙公网安备 33010602011771号