AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

二分法模板

作者: 作者的头像   炼心 ,  2019-11-04 09:22:32 ,  所有人可见 ,  阅读 2051


4


8

二分法模板

很大一部分借鉴于这里

查找大于等于/大于key的第一个元素

这种通常题目描述为满足某种情况的最小的元素。

    int left = 1,right = n;
    while(left < right)
    {
        //这里不需要加1。我们考虑如下的情况,最后只剩下A[i],A[i + 1]。
        //首先mid = i,如果A[mid] > key,那么right = left = i,跳出循环,如果A[mid] < key,left = right = i + 1跳出循环,所有不会死循环。
        int mid = (left + right) / 2;
        if(A[mid] > key)//如果要求大于等于可以加上等于,也可以是check(A[mid])
            right = mid;
        //因为找的是大于key的第一个元素,那么比A[mid]大的元素肯定不是第一个大于key的元素,因为A[mid]已经大于key了,所以把mid+1到后面的排除
        else
            left = mid + 1;
        //如果A[mid]小于key的话,那么A[mid]以及比A[mid]小的数都需要排除,因为他们都小于key。不可能是第一个大于等于key的元素,
    }

三、查找小于等于/小于key的最后一个元素

这种通常题目描述为满足某种情况的最大的元素。如Leetcode69题,求sqrt(x)向下取整就是这种模板。

    int left = 1, right = n;
    while(left < right)
    {
        //这里mid = (left + right + 1) / 2;
        //考虑如下一种情况,最后只剩下A[i],A[i + 1],如果不加1,那么mid = i,如果A[mid] < key,执行更新操作后,left = mid,right = mid + 1,就会是死循环。
        //加上1后,mid = i + 1,如果A[mid] < key,那么left = right = mid + 1,跳出循环。如果A[mid] > key,left = mid = i,跳出循环。
        int mid = (left + right + 1) / 2;
        if(A[mid] < key)
            left = mid;//如果A[mid]小于key,说明比A[mid]更小的数肯定不是小于key的最大的元素了,所以要排除mid之前的所有元素
        else
            right = mid - 1;//如果A[mid]大于key,那么说明A[mid]以及比A[mid]还要大的数都不可能小于key,所以排除A[mid]及其之后的元素。
    }

5 评论


用户头像
さんぜんせかい   2022-08-02 15:51         踩      回复

找了半天,总算是找到模板了,多谢!


用户头像
行走街头   2021-04-13 11:11         踩      回复

orz


用户头像
剑指Rejection   2019-11-26 16:05         踩      回复

感谢dl orz
一直以来都没弄懂mid+1和mid不+1的操作,现在明白了!


用户头像
T-SHLoRk   2019-11-04 14:18         踩      回复

哈哈哈 感谢支持

用户头像
炼心   2019-11-04 18:17         踩      回复

被翻牌了。开心,开心。


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息