classSolution: defsearch(self, nums: List[int], target: int) -> int: # 可以先把最小值找到,然后先看target是否在最小值到最右边之间,不在的话考虑最小值左边,各用二分 # 找到最小值和第二次二分都是Ologn,所以时间Ologn,空间O1 n = len(nums) left = 0 right = n-2 while left <= right: mid = (left+right)//2 x = nums[mid] if target > nums[-1] >= x: # 说明target在第一段,x在第二段 right = mid - 1 elif x > nums[-1] >= target: # 说明target在第二段,x在第一段 left = mid+1 # 下面两种情况都是同一段,按普通二分处理 elif x >= target: right = mid - 1 else: left = mid + 1 return left if nums[left] == target else -1
# 除了下面这种两次二分的办法,也可以判断target、中间值和最后一个值的关系来锁定中间值和target关系 n = len(nums) left = 0 right = n-2 while left <= right: mid = (left+right)//2 if nums[mid] > nums[-1]: left = mid + 1 else: right = mid - 1 min_index = left
# 先排除超出范围的 if nums[min_index] > target or ((min_index > 0and target > nums[min_index-1]) or (min_index == 0and target > nums[-1])): return -1 if nums[min_index] <= target <= nums[-1]: target_index = bisect_left(nums, target, min_index) if nums[target_index] == target: return target_index else: return -1 else: target_index = bisect_left(nums, target, 0, min_index) if nums[target_index] == target: return target_index else: return -1