版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tyhaotingdege/article/details/85844397
题目:给一个非递减数组的旋转数组,求该数组的最小值。
分析题目之前,先知道什么是非递减数组?什么是旋转数组?
非递减数组:数组后面的元素 >= 数组前面的元素。
旋转数组:将数组的前几位,移至数组尾部,构成的新数组称之为原数组的旋转数组。
思路:对于有顺序的数组首先想到的,是二分法查找。
但二分查找时存在一特殊情况,以一次二分查找说明该特殊情况:数组中间值 > 数组最左值,我们便可以肯定最小元素在中间值的右侧。可是只有">"时才有此结论,">="也应我们考虑的范围内,但得不到这个结论的,因为"="时,最小元素依旧可能出现在中间值的左侧,比方说:"1101 1 1111",这种特殊情况是使得我们无法顺利使用二分查找,庆幸的是,这种情况有一个特点:中间值 = 数组最左值 = 数组最右值,我们只需将该情况,特殊处理。剩下的情况便能顺利使用二分查找:数组中间值 >= 数组最左的值时,最小元素在中间值的右侧,指向(最左值的下标)改为指向(中间值的下标);数组中间值 <= 数组最左的值时,最小元素在中间值的左侧,指向(最右值的下标)改为指向(中间值的下标),不断循环判断。
大致思路就是这样,但是还有一个特殊旋转数组要将兼容,即是将数组的前0位,移至数组尾部。数组最右值大于数组最左值的时候,直接返回最左值即可。
代码:
#include <stdio.h>
#include <iostream>
int TraversingArray(int array[], int length);
int TestFunc(int array[], int length)
{
int tmp = 0;
int left = 0;
int right = length - 1;
int mid = 0;
while(array[right] <= array[left])
{
mid = left + (right - left)/2;
if((array == NULL) && (length == 0))
return false;
if(left == (right - 1))
{
mid = right;
break;
}
if((array[mid] == array[left]) && (array[left] == array[right]))
return tmp = TraversingArray(array,length);
if(array[mid] >= array[left])
{
left = mid;
}
else
{
right = mid;
}
}
return array[mid];
}
int TraversingArray(int array[], int length)
{
int n;
int i = 0;
for(i; i<length; i++)
{
if((i+1) < length)
{
if(array[i] > array[i+1])
break;
}
else
return array[i];
}
return array[i+1];
}
int main(int argc, char *argv[])
{
int array[] = {1, 1, 0, 1, 1, 1, 1};
int tmp = TestFunc(array, 7);
printf("min value is : %d\n", tmp);
}