旋转数组的最小数字
问题:把一个数组最开始的若干个元素搬到数组的末尾,我们称他为数组的旋转,输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
首先我们来理解一下什么是旋转数组。例如一个原数组{1,2,3,4,5}我们可以将其变为{2,3,4,5,1},新的数组就是原数组的一个旋转数组,当然{4,5,1,2,3}也是原数组的旋转数组,只是将前面的若干个元素搬到后面。
对于问题一看我们就发现这是一道查找的题,对于查找我们知道的有方法有:顺序查找、二分法查找、哈希查找和二叉排列数查找。对于每一个的查找方法,我们可以根据不同的题目要求,选择不一样的方法。
对于这个题,我们可以选择顺序查找,这个是最简单的方法,我们从头到尾的遍历一遍就可以找到最小的一个元素,时间复杂度为O(n),但是这个题是递增的数组,我们就可以试着用二分法的思路来找这个最小元素。
功能代码如下:
int Min(int *arr,int length)
{
int index1 = 0;
int index2 = length-1;
int indexMid = index1;
while(arr[index1]>=arr[index2])
{
if(index2 -index1 ==1)
{
indexMid = index2
}
indexMid = (index1+index2)/2;
if(arr[indexMid]>=arr[index1])
index1 = indexMid;
if(arr[indexMid]<=arr[index2])
index2 = indexMid;
}
return arr[indexMid];
}
注:从上面我们可以知道对于一个递增数列,如果第一个数字大于最后一个数字,即为两个递增数列,我们可以用刚才的方法,但是如果第一个数字小于最后一个数字,即为一个递增数列,这样的话第一个数字即为最小元素。
但是这种方法也有一种bug,如果遇到如下的结果我们就不能用这种方法,而应该用顺序查找。
所以为了使我们的代码更具有完整性,我们应该在最前面加上一个判断,判断这三个数字是否相等,若相等,则采用顺序查找,若不相等,就采用上诉的那种方法。