可视化图解算法44:旋转数组的最小数字
1. 题目
牛客网 面试笔试TOP101 | LeetCode 153. 寻找旋转排序数组中的最小值
描述
有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。
数据范围:1 ≤n≤10000,数组中任意元素的值: 0 ≤val≤10000
要求:空间复杂度:O(1) ,时间复杂度:O(logn)
示例1
输入:
[3,4,5,1,2]
返回值:
1
示例2
输入:
[3,100,200,3]
返回值:
3
2. 解题思路
根据题目的描述,数组为非降序数组,也就是说数组中的元素是递增的。
定义
- 非降序(Non-decreasing):对于数组中的任意相邻元素
arr[i]
和arr[i+1]
,满足arr[i] ≤ arr[i+1]
。- 允许存在重复元素,但整体趋势不能下降。
示例
- 是非降序的数组:
[1, 2, 3, 4, 5]
[1, 3, 3, 5]
[2, 2, 2]
(所有元素相等)
- 不是非降序的数组:
[5, 3, 1]
(严格递减)[1, 3, 2, 4]
(中间有下降)
如果文字描述的不太清楚,你可以参考视频的详细讲解。
- Python版本:https://www.bilibili.com/cheese/play/ep1372590
- Java版本:https://www.bilibili.com/cheese/play/ep1367846
- Golang版本:https://www.bilibili.com/cheese/play/ep1364844
3. 编码实现
核心代码如下:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
func minNumberInRotateArray(nums []int) int {
// write code here
// 1. 定义变量
left := 0
right := len(nums) - 1
// 2. 通过循环查找旋转数组的最小值
for left < right {
//2.1 找到数组的中间点 mid
mid := (left + right) / 2
// 2.2 缩小区间
if nums[mid] > nums[right] {
left = mid + 1 // 最小值(旋转点)在 [mid+1, right] 中
} else if nums[mid] < nums[right] {
right = mid // 最小值(旋转点)在 [left, mid]中
} else {
// 缩小范围继续判断(特殊情况:旋转之后,尾部出现相同的数据.最小值肯定在后半部分序列中的开始位置)
right--
}
}
return nums[left]
}
具体完整代码你可以参考下面视频的详细讲解。
- Python版本:https://www.bilibili.com/cheese/play/ep1372590
- Java版本:https://www.bilibili.com/cheese/play/ep1367846
- Golang版本:https://www.bilibili.com/cheese/play/ep1364844
4.小结
根据题目的描述,数组为非降序数组,也就是说数组中的元素是递增的。因此最小值肯定在后半部分序列中的开始位置。这时可以通过二分法依次缩小查找区间来找到对应的最小值。
《数据结构与算法》深度精讲课程正式上线啦!七大核心算法模块全解析:
✅ 链表
✅ 二叉树
✅ 二分查找、排序
✅ 堆、栈、队列
✅ 回溯算法
✅ 哈希算法
✅ 动态规划
无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!
- Python编码实现:https://www.bilibili.com/cheese/play/ss897667807
- Java编码实现:https://www.bilibili.com/cheese/play/ss161443488
- Golang编码实现:https://www.bilibili.com/cheese/play/ss63997
对于数据结构与算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。
今日佳句:十年生死两茫茫,不思量,自难忘。