题目描述:
一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5}是由{6,5,4,3,2,1}左移两位形成的,在这种数组中查找某一个数。
分析:
查找数第一反应是二分,而且该数组递减有序,不同的地方是左移了n位。
如果使用二分的话,得到的两个部分将会是这样:一部分递减有序,一部分非有序。
对有序部分可二分查找,对非有序部分,他是该题目的子问题,递归?当然可以。
实际上,利用迭代循环也可以解决。
通过判断array[0]与array[mid]即可判断出哪一部分是有序,
然后可判断num是在有序部分还是非有序部分,(通过if (num > array[mid] && num < array[ low ] ) )
反复调整指针low、high、和mid,即可找到num。
代码如下:
#include <iostream>
using namespace std;
int FindNumber(int arr[], int num, int low, int high)
{
if (arr == NULL)
return -1;
if (low > high)
return -1;
int mid = 0;
while (low <= high)
{
mid = low + (high - low) / 2;
if (arr[mid] == num)
return mid;
else
{
if (arr[low] >= arr[mid])//左边数组是单调递减数组
{
if (num <= arr[low] && num > arr[mid])//要找的数在左边单调数组中
{
high = mid - 1;
}
else//要找的数在右边非单调数组中
{
low = mid + 1;
}
}
else//右边数组是单调递减数组
{
if (num >= arr[high] && num < arr[mid])//要找的数在右边单调数组中
{
low = mid + 1;
}
else//要找的数在左边非单调数组中
{
high = mid - 1;
}
}
}
}
return -1;
}
//测试
int main(int argc,char **argv)
{
int arr[] = {4, 3, 2, 1, 6, 5};
int len = sizeof(arr) / sizeof(*arr);
int num = 1;
int res = FindNumber(arr, num, 0, len - 1);
cout << res << endl;
return 0;
}