33.搜索旋转排序数组
思路:
关键在于判断target、nums[-1]和nums[mid]之间的位置关系:1. target、nums[mid]在同一段,按照之前同样的方法进行左右端点的移动;2. target在第一段nums[mid]在第二段,即target > nums[-1] >= nums[mid](可自行举例验证),需要移动right;3. target在第二段nums[mid]在第一段,即nums[mid] > nums[-1] >= target,需要移动left。
代码:
python
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if target > nums[-1] >= nums[mid]: # target 在第一段,x 在第二段
right = mid - 1
elif nums[mid] > nums[-1] >= target: # x 在第一段,target 在第二段
left = mid + 1
elif nums[mid] >= target: # 否则,x 和 target 在同一段,与之前方法类似
right = mid - 1
else:
left = mid + 1
return left if nums[left] == target else -1
复杂度分析:
- 时间复杂度:O(logn),其中 n 为 nums 的长度。
- 空间复杂度:O(1)。
153.寻找排序数组中的最小值
思路:
把 x 与最后一个数 nums[−1] 比大小:
- 如果 x>nums[n−1],那么可以推出以下结论:
nums 一定被分成左右两个递增段;第一段的所有元素均大于第二段的所有元素;x 在第一段,最小值在第二段。所以x 一定在最小值的左边 。
- 如果 x≤nums[n−1],那么 x 一定在第二段。(或者 nums 就是递增数组,此时只有一段。)x 要么是最小值,要么在最小值右边。
参考:
代码:
python
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] <= nums[-1]:
right = mid - 1 # 此时nums[mid]要么是最小值,要么在最小值右边
else:
left = mid + 1
return nums[left]