153. 寻找旋转排序数组中的最小值
1、题目
已知一个长度为 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] ,旋转 3 次得到输入数组。
示例 3:
输入:nums = [11,13,15,17] 输出:11 解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
提示:
n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums
中的所有整数 互不相同nums
原来是一个升序排序的数组,并进行了1
至n
次旋转
Related Topics
- 数组
- 二分查找
2、题目分析
定理一:若存在乱序区间,旋转数组最小值往往存在于乱序区间。否则,最小值在区间最左边。
定理二:如何找乱序区间
- 若mid大于右边界的值,则乱序区间在mid右边。
- 若mid小于左边界的值,则乱序区间在mid左边。
- 不存在乱序区间,区域最小值就是区域最左边。
定理三:每次二分,至多存在一个乱序区间,即要么有一个乱序区间,要么没有乱序区间。
若通过不断的用Mid二分,根据定理二,找乱序区间,如果存在乱序区间,下次循环就直接取乱序区间,如果不存在,那么直接取区域最左值。
3、复杂度最优解代码示例
public int findMin(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[right]) {
// 1、乱序区间存在于区域二分点右边。往右边找,因为数组最小值在乱序区间中。
left = mid + 1;
} else if (nums[mid] < nums[left]) {
// 2、乱序区间存在于区域二分点左边。往左边找,因为数组最小值在乱序区间中。
right = mid;
} else {
// 3、乱序区间不存在,则数组最小值处于区域最左边。
// (乱序区间不存在:意味着二分中间值 > 区域左边界值,且二分中间值 < 区域有边界值。此时该区域单调递增,未被旋转)
return nums[left];
}
}
return nums[left];
}
4、适用场景
寻找旋转排序数组中的最小值的适用场景包括:
- 数据恢复:在数据恢复场景中,可能需要从损坏的数据文件中提取信息,这些文件可能因为某些操作导致数据的排序发生了旋转,需要找到最小值进行修复。
- 数据库查询优化:在数据库中,如果索引因为某些操作如大量数据的插入或删除而变得不再连续,可能需要在旋转排序数组中进行查找以优化查询。
- 股票市场分析:历史价格数据可能会因为时间窗口的变换而形成旋转排序数组,分析师需要快速找到某个时间段内的最低股票价格。
- 游戏开发:在游戏中,排行榜或者分数列表可能因为玩家的加入和退出而变得不连续,需要快速找到排名最低的玩家。
- 实时系统:在实时系统中,如果数据流因为时间戳的变化而被分割成多个部分,寻找旋转排序数组中的最小值可以帮助快速定位最新的数据点。
- 机器学习特征选择:在机器学习中,特征选择可能需要在一组旋转排序的特征值中搜索最优的特征分割点。
- 图像处理:在图像处理中,可能需要在一组旋转排序的像素值中搜索特定的颜色或亮度值。
- 生物信息学:在基因序列分析中,可能需要在一组旋转排序的DNA序列中搜索特定的模式或序列。
- 算法竞赛和面试:寻找旋转排序数组中的最小值是算法竞赛和编程面试中常见的问题,考察候选人对二分查找算法的理解和灵活应用能力。
在这些场景中,使用修改的二分查找算法来寻找旋转排序数组中的最小值是非常有效的,因为它可以在O(log n)的时间复杂度内找到目标值,大大提高了搜索效率。