代码题--C++--旋转数组求最小值
题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。
输入描述:
一个排好序的数组的一个旋转
数组长度不超过1000000
输出描述:
该数组的最小值
示例1
输入
3 4 5 1 2
输出
1
解题思路:
使用二分查找的方法,逐步的逼近这个最小值,首先这个旋转数组将一个非递减的数组分成了两个子数组,前一个数组的值都比后一个数组的值大,并且两个子数组都是非递减的数组,而且我们可以知道这个最小值肯定是在前一个数组和后一个数组的交界出。也就是后一个数组的第一个值。
采用二分法解答这个问题,mid = low + (high - low)/2;
需要考虑三种情况:
(1)array[mid] > array[high]
出现这种情况array类似[3, 4, 5, 0, 1],此时最小数字移动在mid的右边。low = mid + 1;
(2)array[mid] == array[high]
出现这种情况array类似[0, 1, 1, 1, 1,]或者[1, 1, 1, 0, 1],此时最小数字不好判断在mid左边还是右边,只好一个个的试。high = high - 1;
(3)array[mid] < array[high]
出现这种情况的array类似[2,3,4,5,6],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。 high = mid;
注意:如果待查询的范围最后只剩两个数,那么mid 一定会指向下标靠前的数字
比如 array = [4,6]
array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ;
如果high = mid - 1,就会产生错误, 因此high = mid
但情形(1)中low = mid + 1就不会错误
完整C++代码如下:
#include <iostream>
using namespace std;
#include <vector>
int Xuanzhuan_min(vector<int> vec)
{
int res = 0;
int low = 0;
int size = vec.size();
int high = size - 1;
if(size==0)
return 0;
//1.vec[mid] == vec[high]; high = high -1;
//2.vec[mid] >= vec[high] ;low = mid +1;
//3.vec[mid] <= vec[high] ;high = mid;
while (low < high)
{
int mid = low + (high - low) / 2;
if (vec[mid] > vec[high])
{
low = mid + 1;
}
else if (vec[mid] == vec[high])
{
high = high - 1;
}
else
{
high = mid;
}
}
res = vec[low];
return res;
}
int main()
{
vector<int> vec ;
char ch;//由于数组长度不确定,采用字符读取,然后再转为数字,压入vector中。
int num = 0;
while((ch = getchar()) != '\n'){
if(ch != ' '){
num = 10 * num + (ch - '0');
} else {
vec.push_back(num);
num = 0;
}
}
vec.push_back(num);
int res = Xuanzhuan_min(vec);
cout << res;
return 0;
}