旋转数组的最小数字
题目:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1
这一题看似一遍循环就能解决,的确,一遍循环就能解决,但是面试官肯定不会是考察你循环会不会写。
我们来寻求一下简单一点的办法。
从题目中可以知道,数组被分成了两个递增的序列,而且最小的数字就是两个序列的分界线。刚刚用一次遍历的时间复杂度为O(n),但是如果我们采用二分查找来实现的话,可以把复杂度降到O(logn)。做法如下:
1、用两个指针,分别指向数组的第一个元素和最后一个元素
2、选取中间的元素,如果该元素比第一个元素大(或者相等),那最小的肯定在后半部分。反之则在前半部分。
3、循环往复,最终就能确定最小元素的位置
二分查找还是比较容易实现的
代码
int Min(int* numbers,int length)
{
if(numbers==nullptr || length<=0)
throw new std::exception("Invalid parameters");
int index1=0;
int index2=length-1;
int indexMid=index1;
while(numbers[index1]>=numbers[index2])
{
if(index2-index1==1)
{
indexMid=index2;
break;
}
indexMid=(index1+index2)/2;
if(numbers[indexMid]>=numbers[index1])
index1=indexMid;
else if(numbers[indexMid]<=numbers[index2])
index2=indexMid;
}
return numbers[indexMid];
}
———————————————————————————————————————————————————————————
参考书籍:《剑指offer 第二版》