神奇的二分查找,轻松过oj

对于我们现在所学的知识,在一个数组中寻找关键数或者关键字符很容易,但是很多acmer在oj上永远都是wa或者超时,让人焦头烂额啊!!!

最简单的查找方式就是暴力求解,说白了就是从头遍历到尾,运气好的话就是第一个(如果是这样,你去玩彩票去吧),运气不好的话,嘿嘿,你知道n有多大嘛?

首先我们先探讨暴力求解和二分查找的时间复杂度吧

1.暴力求解

在一个数组中,如果采用遍历的方式去寻找关键字,则需要从i=0(或者i=1,这个根据个人习惯)开始遍历,知道找到关键字返回下标值,否则从头遍历到尾,我们做最坏的打算就是n了。也就是说暴力求解的时间复杂度为o(n)。

2.二分查找

我们现在假定有一个数组a[6]={1,5,3,7,4,8},其n=6,假如我们需要查找的数字key=8,二分顾名思义就是一分为二嘛,所以说我们可以把数组拆成两半,怎么拆嘞,容旺仔小胜娓娓道来。

因为n=6,所以我们可以定义一个变量mid(中间的意思),即mid=n/2,由此可以算出mid=3,然后将a[mid](a[3])与key进行比较,假如比key小,就说明key正在数组的右半部分,反之(到这里还能理解吧???),在这里我教大家怎么去用代码实现(部分伪代码)

    int a={1,5,3,7,4,8}
    int l=1;
    int r=6;
    int ans=-1;
    int mid;
    int key=8;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(a[mid]==key)
        {
            ans=mid;
            break;
        }
        if(a[mid]>key)
        {
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ans;//得出关键字的下标索引值

看这里,代码中可能引入了一些新的变量,l,r分别表示的是数组的最左边和最右边的下标索引值,当确定关键数组在那一半时,则要确定那一半为一个新的数组,舍弃另一半的数组,所以会出现为啥会有r=mid-1或者l=mid+1(为啥是这个,留给自己琢磨一下吧!!!)

我们再来算算时间复杂度吧,通俗点,一半的一半的一半......不就是反复除以二嘛???就好像n,反复去除以2最终等于1,反过来推就2^x=n,即x=\log{n},这样看来,是不是时间上少了很多。

要睡觉了,就写到这里吧,完整代码就在下面!!!

#include<iostream>
using namespace std;
const int N=1e6;
int arr[N];
int binarysearch(int arr[],int n,int x)
{
    int l=1;
    int r=n;
    int ans=-1;
    int mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(arr[mid]==x)
        {
            ans=mid;
            break;
        }
        if(arr[mid]>x)
        {
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ans;
}
int main()
{
    int n,key,ans;
    cin>>n>>key;
    for(int i=1;i<=n;i++)
        cin>>arr[i];
    ans=binarysearch(arr,n,key);
    cout<<ans<<endl;
    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值