每日一题:LeetCode-153. 寻找旋转排序数组中的最小值
刷题使我快乐,满脸开心.jpg
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
已知一个长度为 n
的数组,预先按照升序排列,经由 1
到 n
次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7]
在变化后可能得到:若旋转 4
次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7
次,则可以得到 [0,1,2,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
,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
示例 2:
示例 3:
提示:
n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums
中的所有整数 互不相同nums
原来是一个升序排序的数组,并进行了1
至n
次旋转
思路
二分法
明显的提示,用二分
这里传统的二分可能会陷入思维陷阱,因为传统二分,用边界做基准,此时因为基准的不断变化,会导致思路难度飙升,感觉就算可以解答也会非常复杂
基准
那就找个基准
其实很容易找到,那就是数组中位置 0
和len(nums)-1
。理论上都可以,但是这里我更推荐0
因为基准如果恰好是最小值,感觉上会增加思维的复杂度(其实并不一定,但是我本人喜欢剥离开思考问题)
而0
如果是最小值,恰好是一个特殊情况,恰好旋转回了原始数组
,只有此种情况下:
nums[0] <= nums[len(nums)-1]
等于是只有一个元素的情况
二分思路
放个图辅助说明,二分思路其实很简单,因为除了上述特殊情况下
如果
nums[mid] >= nums[0]
,那最小值一定在右边如果
nums[mid] < nums[0]
,那最小值一定在左边
特殊情况
那肯定有人会担心,如果恰好mid
在最小值怎么办,上面的判断不成立了啊!不用担心,我们用外循环的一个小技巧就能覆盖住
正常来讲,二分法的外循环根据不同题目,会是 left < right
或者 left <= right
,但是这道题我的思路下
必须用 left <= right
因为在如图中,
mid
恰好在最小值的情况下,区间会走到左边
此时区间内所有数字都比
nums[0]
大,所以会不断累加 left,直到left = right + 1
退出
而此时,也就恰好覆盖住了特殊的情况,找到了右边界右边的这个最小值
OK,思路基本就说完了,老样子,细节在代码注释了~
代码
版权声明: 本文为 InfoQ 作者【半亩房顶】的原创文章。
原文链接:【http://xie.infoq.cn/article/3ef96c94bae291d9996c00e07】。文章转载请联系作者。
评论