现在的位置: 首页 > 综合 > 正文

笔试题,在部分有序的数组中寻找给定值

2013年09月03日 ⁄ 综合 ⁄ 共 1571字 ⁄ 字号 评论关闭

 

题有很多变种:

1.第一种 将一个有序数组循环移位K位后,最少要几个数就可以判断原数组的增减性

解答:将三个数假定为是abc,如果大小关系为[bac,acb,cba]可以知道原数组是递增的.反之为递减

2.在一个已知循环移位的有序数组上查找原数组的开始位置【根据1中方法判断递增或者递减】

 解答:【假如是递增】采用二分搜索的方法,每次搜索的时候将当前的值和[low]低端的值进行比较判断处于哪一边

         如果s[mid] > s[low]那么说明开始位置在 [mid,high] 区间中

         如果s[mid] < s[low] 那么说明开始位置在[low,mid]区间中

int f(int* a,int i,int j)
{
    int m=0;
    while(i<j+2)
    {
        if (j-i==1)
          return a[i]<a[j]?i:j;
        m=(i+j)/2;
        if(a[m]>a[i])
            {
                i=m;
                m=(i+j)/2;
            }
        else
        {
            j=m;
            m=(i+j)/2;
        }
    }
}

以上程序默认数组是递增的。返回的是原数组开始位置。

3.在一个已知循环移位的有序数组上查找给定的值

 解答:首先通过1将数组的增减性判断好,假设是递增,综合mid 当前查找的值 以及两端的值判断 要查找的值的范围,不断缩小这个范围,即可。

int find(int* s,int low,int high,int m)
{
    int mid;
    while (low+1<high)
    {
        mid = low + (high -low)/2;
        if (s[mid] == m)
        {
            return mid;
        }
        if (m > s[mid])
        {
            if (s[mid] > s[low])
            {
                low = mid;
            }
            else
                if (m>=s [high])
                {
                    high = mid;
                }
                else
                    low = mid;
        }
        else
        {
            if (s[mid] > s[low])
            {
                if (m >= s[low])
                {
                    high = mid;
                }
                else
                    low = mid;
            }
            else
                high = mid;
        }
    }
    if (s[low] == m)
    {
        return low;
    }
    if (s[high] == m)
    {
        return high;
    }
    return -1;

}

 

4.如果一个数组 前一部分是递增后一部分也是递增的,在其中查找给定值

 这个比较纠结

5. 果一个数组 前一部分是递增后一部分是递减的,在其中查找给定值

 解答:判断数组的后两个元素,测试后一部分是否有递减的部分。没有,直接二分就可以

如果存在递减的部分,那么先用二分搜出两部分区域,然后再二分搜索。 

转自:http://www.cnblogs.com/davidluo/articles/1837561.html

抱歉!评论已关闭.