非遞減旋轉數組找最小值
題目
給一個非遞減數組的旋轉數組,求該數組的最小值。
瞭解
分析題目之前,先知道什麼是非遞減數組?什麼是旋轉數組?
非遞減數組:數組後面的元素 >= 數組前面的元素。
旋轉數組:將數組的前幾位,移至數組尾部,構成的新數組稱之爲原數組的旋轉數組。
思路
對於有順序的數組首先想到的,是二分法查找。
但二分查找時存在一特殊情況,以一次二分查找說明該特殊情況:數組中間值 > 數組最左值,我們便可以肯定最小元素在中間值的右側。可是隻有">"時纔有此結論,">="也應我們考慮的範圍內,但得不到這個結論的,因爲"="時,最小元素依舊可能出現在中間值的左側,比方說:"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);
}