527 字
3 分钟
LeetCode-153. 寻找旋转排序数组中的最小值
二分查找
已知一个长度为
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:
输入:nums = [3,4,5,1,2]输出:1解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。示例 2:
输入:nums = [4,5,6,7,0,1,2]输出:0解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。示例 3:
输入:nums = [11,13,15,17]输出:11解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
思路
这是个经典解法,关于它主要有两个令人疑惑的点:
- 他的输出最小值依靠left,所以他的循环条件是
left < right最终会停留在left = mid = right的时候,而不是<= - 因为
mid这个值也有可能是答案,如果是right = mid-1就会把这个值排除了,与平常求target是已经与target比较后被排除后才right = mid-1,不是一个情况
func findMin(nums []int) int { left, right := 0, len(nums)-1
for left < right { mid := left + (right - left)/2
if nums[mid] < nums[right] { right = mid } else { left = mid + 1 } } return nums[left]}手撕的思路
看到题目只对时间复杂度做了要求,就引入num储存最小值
func findMin(nums []int) int { left, right := 0, len(nums)-1 num := 5001
for left <= right { mid := left + (right - left)/2
if nums[left] <= nums[mid] { num = min(num, nums[left]) left = mid + 1 }else { num = min(num, nums[mid]) right = mid - 1 } } return num} LeetCode-153. 寻找旋转排序数组中的最小值
https://sheep44044.github.io/posts/算法/二分查找/leetcode-153-寻找旋转排序数组中的最小值/