环有序数组查找

来源:互联网 发布:淘宝宝贝长图的重要性 编辑:程序博客网 时间:2024/05/16 06:54
 

最近看到一个蛮有意思的题,说的是一个数组环有序,例如1,2,3,4,-22,-1 0,问说怎么在O(log n)时间内找到某个元素的索引?

其实看到O(log n),应该很自然的想到二分查找,但是数组环有序,所以需要对二分查找做一定改动。

我的想法是把数组分为两个有序区,以v[0]为基准,大于等于v[0]的区域为一区,小于v[0]为二区。如下所示:

   1, 2, 3, 4,   -22, -1, 0

|<-    1区   ->|<- 2区 ->|

在查找的时候,根据目标元素与基准的大小比较确定目标搜索区间,如果当前目标区间与目标搜索区间不一致,则到另外一个有序区间进行搜索,否则仍然按照原来的二分查找进行搜索。

我的代码如下,已测试:

#include <iostream>
using namespace std;

int CircleSearch(int data[], int len, int value)
{
        if (len <1)     return -1;
        int low = 0, high = len-1, mid;
        while (low <= high)
        {
                mid = low + (high-low)/2;
                if (value == data[mid]) return mid;
                if (value > data[mid])
                {
                        if (data[mid] < data[0] && value >= data[0]) //如果当前搜索区间为二区,且它不是目标搜索区间
                                high = mid - 1;
                        else
                                low = mid + 1;
                }
                else
                {
                        if (data[mid] > data[0] && value < data[0]) //如果当前搜索区间为二区,且它不是目标搜索区间
                                low = mid + 1;
                        else
                                high = mid - 1;
                }
        }
        return -1;
}
//测试
int main()
{
        int data[10] = {1,2,3,4,5,-4,-3,-2,-1,0};
        int index = CircleSearch(data,10,-1);
        if (index >= 0)
                cout << "the index is : " << index << endl;
        else
                cout << "can not find!" << endl;
        return 0;
}
总结:这一题比较简单,是很基本的二分查找的变种,既考了基本功且蛮有趣味,是蛮好的用来动脑筋的一道题。

 

原创粉丝点击