二分总结

本文详细介绍了二分搜索的不同应用场景及其实现方式,包括查找数组中第一个大于给定值的元素和最后一个小于给定值的元素等。同时,还提供了一种查找指定元素并返回最左侧位置的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/int64ago/article/details/7425727

今天求最长非递减子序列的时候,用lower—bound一直wa,百思不得其解,最后想明白不是找第一个大于等于的数,而是找到第一个大于的数。所以只能自己手写二分了,原来一直以为二分很简单,但是今天写了之后发现总是有各种小错误。比如while (left < right)和while (left <= right) 的选择,比如a[mid] > key 和a[mid] >= key 的选择。直到看到上面那篇博客,受益匪浅,不过就我今天写的题还有一些要添加的内容。

先贴出上面博客的几种情况的二分

Hint: begin是第一个元素的下标,end是最后一个元素的下标加1

YES_LEFT (如果有多个元素,返回最左边一个元素的下标)或 NO_RIGHT(如果没有,返回key可以插入位置的下一个元素下标)

int Binary_search(int begin, int end, int key)  
{  
    int left = begin, right = end, mid;  
    while(left <= right)  
    {  
        mid = (left + right) >> 1;  
        if(num[mid] >= key) 
            right = mid - 1;  
        else left = mid + 1;  
    }  
    return left;  
} 
YES_RIGHT(如果有多个元素,返回最右边一个元素的下标) 或 NO_LEFT(如果没有,返回key可以插入位置的前一个元素)

    int Binary_search(int begin, int end, int key)  
    {  
        int left = begin, right = end, mid;  
        while(left <= right)  
        {  
            mid = (left + right) >> 1;  
            if(num[mid] > key) 
                right = mid - 1;  
            else left = mid + 1;  
        }  
        return right;  
    }  
但是我今天需要的并不是上面任何一种的二分,我要求的二分是,返回一个数组中第一个大于key的值的下标

int Binary_search(int begin, int end,int key)
{
    int left = begin, right = end, mid;
    while(left <= right)
    {
        mid = (left + right) >> 1;
        if(num[mid] > key)
            right = mid - 1;
        else left = mid + 1;
    }
    return left;
}
那么还有最后一种二分,它的功能是找出最后一个比key值小的元素的下标,如果所有元素都大于等于key,返回0。
int Binary_search(int begin, int end, int key)
{
    int left = begin, right = end, mid;
    while(left <= right)
    {
        mid = (left + right) >> 1;
        if(num[mid] >= key)
            right = mid - 1;
        else left = mid + 1;
    }
    return right;
}
上面四种代码可以实现我们想要的功能,假如我们现在想要的功能是,查找元素,如果有多个,返回最左边的下标,如果没有,返回-1。我们可以从YES_LEFT修改得出,

只要最后判断返回下标所代表的元素是不是key,就可以知道key到底存在不存在。

int Binary_search(int begin, int end, int key)
{
    int left = begin, right = end, mid;
    while(left <= right)
    {
        mid = (left + right) >> 1;
        if(num[mid] >= key)
            right = mid - 1;
        else left = mid + 1;
    }
    if (num[left] == key)
        return left;
    else return -1;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值