153. 旋转数组最小值
2019-06-03 本文已影响0人
霍尔元件
刷题内容
原题连接
内容描述
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]).
Find the minimum element.
You may assume no duplicate exists in the array.
Example 1:
Input: [3,4,5,1,2]
Output: 1
Example 2:
Input: [4,5,6,7,0,1,2]
Output: 0
思路一: 唯一下降子序列
class Solution:
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
for i in range(1, len(nums)):
if nums[i] < nums[i - 1]:
return nums[i]
return nums[0]
思路二: 证明法
带证明的解法
left < right ==> mid < right 因为mid可能等于left但是绝对不可能等于right
nums[mid] != nums[right]
所以可以比较nums[mid] 和 nums[right] 并且只有两种情况
- nums[mid] > nums[right] 说明最小值在右半段
可以推出nums[mid]不可能是最小值 所以可以放心的让 left = mid + 1 - nums[mid] < nums[right] 说明最小值在左半端 不能让right = mid - 1
因为mid可能是最小值 只能够是 right = mid 那么这样会不会使得区间不收缩 陷入死循环呢 答案是不会 因为 mid < right 区间必然收缩 - 当while的判断条件不再满足 left == right 找到最优解
class Solution:
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]:
left = mid + 1
else:
right = mid
return nums[left]
思路三: 混合
class Solution(object):
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
if nums[mid] < nums[mid - 1]: # 数组中唯一一个逆序 序列 找到之后直接返回
return nums[mid]
elif nums[mid] < nums[l]: # mid 位于右段 target位于左段 因为确定mid位置不会是最小值 所以可以放心地令 right = mid - 1
r = mid - 1
elif nums[mid] > nums[r]: # mid 位于左段 target位于右段 因为nums[mid]不可能是最小值
l = mid + 1
else: # 处理只有一个元素的情况 [1]
return nums[l]