假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组
[0,1,2,4,5,6,7]
可能变为[4,5,6,7,0,1,2]
)。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回
-1
。你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别
二分法,只要注意二分的范围即可。
class Solution:
def search(self, nums: List[int], target: int) -> int:
left,right = 0,len(nums) - 1
while left <= right:
middle = (left + right) >> 1
if nums[middle] == target: return middle
if nums[left] <= nums[middle]:
if nums[left] <= target < nums[middle]: right = middle - 1
else: left = middle + 1
else:
if nums[middle] < target <= nums[right]: left = middle + 1
else: right = middle - 1
return -1
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组
[0,0,1,2,2,5,6]
可能变为[2,5,6,0,0,1,2]
)。编写一个函数来判断给定的目标值是否存在于数组中。若存在返回
true
,否则返回false
。
跟上面的区别就只是多加一个重复判断。
class Solution:
def search(self, nums: List[int], target: int) -> bool:
left,right = 0,len(nums) - 1
while left <= right:
middle = (left + right) >> 1
if nums[middle] == target: return True
if nums[left] == nums[middle] == nums[right]:
left += 1
right -= 1
continue
if nums[left] <= nums[middle]:
if nums[left] <= target < nums[middle]: right = middle - 1
else: left = middle + 1
else:
if nums[middle] < target <= nums[right]: left = middle + 1
else: right = middle - 1
return False
上面是两个常见的旋转排序类型的题。除此之外,另一种类型的题是寻找最小值,注意这个时候要和右边的值判断,而且二分的写法也略有不同。
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组
[0,1,2,4,5,6,7]
可能变为[4,5,6,7,0,1,2]
)。请找出其中最小的元素。
你可以假设数组中不存在重复元素。
class Solution:
def findMin(self, nums: List[int]) -> int:
left,right = 0,len(nums) - 1
while left < right:
middle = (left + right) >> 1
if nums[middle] > nums[right]:
left = middle + 1
else:
right = middle
return nums[left]
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组
[0,1,2,4,5,6,7]
可能变为[4,5,6,7,0,1,2]
)。请找出其中最小的元素。
注意数组中可能存在重复的元素。
class Solution:
def findMin(self, nums: List[int]) -> int:
left,right = 0,len(nums) - 1
while left < right:
middle = (left + right) >> 1
if nums[middle] == nums[right]:
right -= 1
continue
if nums[middle] > nums[right]:
left = middle + 1
else:
right = middle
return nums[left]