原题:
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
题目大意是:在O(log n)时间内在循环有序列表中寻找一个数,并返回它的位置。若不存在,则返回-1。
很明显,该问题需要用到二分查找,虽然该列表并不是有序的,但我们可以寻找规律,以进行二分查找,我们知道二分查找中有三个位置变量:first、mid和last。然后我们进行分类讨论:
- 若nums[mid]>nums[first],则证明从first到mid都是递增的。此时,若target<nums[mid]且target>nums[first],则证明target在mid的左侧,其余情况下target在mid的右侧。
- 若nums[mid]<=nums[first],则证明从first到mid之间有最小值。此时,若target>nums[mid]且target<nums[first],则证明target在mid的右侧,其余情况下在mid的左侧。
至此,算法已构建完毕,代码写起来就简单多了:
class Solution:
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
n = len(nums)
first = 0
last = n-1
if n == 0:
return -1
while(first < last):
mid = int((first + last) / 2)
if nums[first] <= nums[mid]:
if target == nums[mid]:
return mid
elif target == nums[first]:
return first
elif target < nums[mid] and target > nums[first]:
last = mid
else:
first = mid+1
else:
if target > nums[mid] and target < nums[first]:
first = mid+1
elif target == nums[mid]:
return mid
elif target == nums[first]:
return first
else:
last = mid
if nums[first] == target:
return first
else:
return -1