持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
一、题目
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,4] 若旋转 7 次,则可以得到 [0,1,4,4,5,6,7] 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个可能存在 重复 元素值的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须尽可能减少整个过程的操作步骤。
示例 1:
输入:nums = [1,3,5]
输出:1
示例 2:
输入:nums = [2,2,2,0,1]
输出:0
作者:力扣 (LeetCode) 链接:leetcode.cn/leetbook/re… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二、思考
二分查找
# 这道题是153的升华版
# 首先还是先思考这个数组,这个数组分为三种情况,
# 第一种情况,就是nums[mid]小于nums[right],这说明什么问题呢,
# 这说明了nums[mid]是右区间的最小值,这时我们可以忽略了这部分区间
# 第二种情况是nums[mid]大于nums[right],从第一种情况对比,
# 这时得到的结果是最小值就在下标mid与right之间,这时我们可以定义最小的左区间的开始位置
# 开始位置为left = mid + 1
# 在153中,因为不存在重复元素,所以只要区间的长度为1时,就找到了当前最小值得位置
# 但是,现有的list中元素是存在重复的,那么就有一个问题了,就是相等的情况
# 因为nums[mid] 等于 nums[right],这时无法选择到底是left加还是right减
# 假设当前长度为2时,那么nums[mid]其实就是最小的值了,那么这样就可以忽略右区间了,因此right 减 1
其他思路
例如sort排序,min取最小值等等
三、代码
nums = [11,13,15,17]
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = left + ((right - left)//2)
if nums[mid] < nums[right]:
right = mid
elif nums[mid] > nums[right]:
left = mid + 1
else:
right -= 1
return nums[left]
Solution().findMin(nums)