【面试题】有序数组截断、交换后的查找算法 C语言实现

此类算法题思路参考来自:博客

但是查找截断位置二分好像很复杂的样子,不太好写。这里我用倍增的思想代替上面的二分。

每次尝试走2^i 次方,类似于求LCA的方法。

找到截断位置后,再分别两个地方进行二分查找

并且用C语言实现

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n;
int f[30];
int main()
{
    f[0]=1;
    for(int i=1;i<=20;++i) f[i]=f[i-1]*2;
    scanf("%d",&n);
    for(int i = 1;i <= n; ++i) scanf("%d",&a[i]);
    

    int now=1;
    for(int i = 20; i >= 0; --i){
        if(now + f[i] > n) continue;
        if(a[now + f[i]] >= a[now]) now = now + f[i];
    }
    int ans;
    if(now == n) ans = 1;
    else ans = now + 1;
    

    printf("ans:%d\n",ans);//截断处

    int m;scanf("%d",&m);//查询个数
    while(m--)
    {
        int x;
        scanf("%d",&x);

        int l = ans,r = n;

        int flag = 0;

        if(a[l] <= x && x <= a[r]){
            int res = -1;
            while(l <= r)
            {
                int mid = l + r >> 1;
                if(a[mid] >= x){
                    res = mid;
                    r = mid - 1;
                }
                else l = mid + 1;
            }
            if(res != -1){
                if(a[res] == x) flag=1;
            }
        }
        l = 1,r = ans - 1;
        if(a[l] <= x && x <= a[r]){
            int res = -1;
            while(l <= r)
            {
                int mid = l + r >> 1;
                if(a[mid] >= x){
                    res = mid;
                    r = mid - 1;
                }
                else l = mid + 1;
            }
            if(res != -1){
                if(a[res] == x) flag=1;
            }
        }

        if(flag){
            puts("Yes");
        }
        else puts("No");


    }


}
/*
8
12 20 34 77 1 4 7 10
100


10
6 8 9 10 1 2 3 4 5 6

*/

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/106593882