剑指offer(C++)-JZ11:旋转数组的最小数字(算法-搜索算法)
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer(C++)-JZ11:旋转数组的最小数字(算法-搜索算法)相关的知识,希望对你有一定的参考价值。
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
题目描述:
有一个长度为 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)
示例:
输入:
[3,4,5,1,2]
返回值:
1
解题思路:
本题考察算法-搜索算法的使用。二分查找思想,具体思路如下:
- 左右边界初始设在数组两端,二分法压缩搜索区域。
- 若中间值高于右边界值,考虑到旋转数组旋转前的升序特性,左边界值应该等于或大于右边界值,也就是说最小值是在中间值的右侧,因此将左边界设在中间+1的位置。
- 若中间值等于右边界值,很大概率中间值到右边界值的这段区域都是同一数值,因此我们将右边界左移后再尝试。
- 若中间值低于右边界值,毫无疑问,中间值到右边界值的过程是升序的,那最小值要么就是中间值,要么就在中间值左侧,因此将右边界设在中间值位置,继续查找。
测试代码:
class Solution
public:
int minNumberInRotateArray(vector<int> rotateArray)
// 确定左右边界
int left = 0;
int right = rotateArray.size() - 1;
// 二分查找
while(left < right)
int mid = (left + right) / 2;
// 目标在右边
if(rotateArray[mid] > rotateArray[right])
left = mid + 1;
// 无法判断,将右边界压缩再试
else if(rotateArray[mid] == rotateArray[right])
right--;
// 最小数字要么是mid要么在mid左边
else
right = mid;
return rotateArray[left];
;
以上是关于剑指offer(C++)-JZ11:旋转数组的最小数字(算法-搜索算法)的主要内容,如果未能解决你的问题,请参考以下文章
剑指offer(C++)-JZ11:旋转数组的最小数字(算法-搜索算法)
剑指 Offer(C++版本)系列:剑指 Offer 11 旋转数组的最小数字
剑指 Offer(C++版本)系列:剑指 Offer 11 旋转数组的最小数字