当前位置: 首页 > news >正文

二分的模板(花式二分)

作者:李冠华
链接:http://www.zhihu.com/question/36132386/answer/105595067
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

对于不下降序列a,n为序列a元素的个数,key为关键字:
1.求最小的i,使得a[i] = key,若不存在,则返回-1
int binary_search_1(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) >> 1);//向下取整
        if (a[m] < key) l = m + 1;
        else r = m;
    }
    if (a[r] == key) return r;
    return -1;
}
2.求最大的i,使得a[i] = key,若不存在,则返回-1
int binary_search_2(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r + 1 - l) >> 1);//向上取整
        if (a[m] <= key) l = m;
        else r = m - 1;
    }
    if (a[l] == key) return l;
    return -1;
}
3.求最小的i,使得a[i] > key,若不存在,则返回-1
int binary_search_3(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) >> 1);//向下取整
        if (a[m] <= key) l = m + 1;
        else r = m;
    }
    if (a[r] > key) return r;
    return -1;
}
4.求最大的i,使得a[i] < key,若不存在,则返回-1
int binary_search_4(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r + 1 - l) >> 1);//向上取整
        if (a[m] < key) l = m;
        else r = m - 1;
    }
    if (a[l] < key) return l;
    return -1;
}
实际上,对于3、4,也可以先判断解是否存在,再进行二分查找。

显然,上面的代码还不够简洁。下面给出我认为最简洁的代码:
1.
int ans = std::lower_bound(a, a + n, key) - a;
ans = (ans == n || a[ans] != key) ? -1 : ans;
2.
int ans = std::upper_bound(a, a + n, key) - a;
ans = (ans == 0 || a[ans - 1] != key) ? -1 : ans - 1;
3.
int ans = std::upper_bound(a, a + n, key) - a;
ans = (ans == n) ? -1 : ans;
4.
int ans = std::lower_bound(a, a + n, key) - a;
ans = (ans == 0) ? -1 : ans - 1;

相关文章:

  • STL之set集合容器
  • NOIP2016#模拟考试 Day.1# T1 洗澡
  • NOIP2016#模拟考试 Day.1# T3 导航软件
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • NOIP2016#模拟考试 Day.2# T2 网络修复 【LCA + 并查集】
  • NOIP2016#模拟考试 Day.2# T3 王位继承
  • [hdu 2826] The troubles of lmy [简单计算几何 - 相似]
  • [hdu 2896] 病毒侵袭 [ac自动机][病毒特征码匹配]
  • [hdu 3065] 病毒侵袭持续中 [AC自动机] [病毒特征码匹配]
  • TCP/IP协议讲解 一
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #NOIP 2014# day.1 T2 联合权值
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #NOIP 2014# day.2 T2 寻找道路
  • 【node学习】协程
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • ES6语法详解(一)
  • JavaScript中的对象个人分享
  • JavaWeb(学习笔记二)
  • Java知识点总结(JavaIO-打印流)
  • k8s如何管理Pod
  • mysql中InnoDB引擎中页的概念
  • Web标准制定过程
  • 判断客户端类型,Android,iOS,PC
  • 删除表内多余的重复数据
  • 微信公众号开发小记——5.python微信红包
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • #13 yum、编译安装与sed命令的使用
  • #14vue3生成表单并跳转到外部地址的方式
  • (2)STM32单片机上位机
  • (4)(4.6) Triducer
  • (4.10~4.16)
  • (7)STL算法之交换赋值
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (算法设计与分析)第一章算法概述-习题
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)基于IDEA的JAVA基础1
  • (转)nsfocus-绿盟科技笔试题目
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .net core 依赖注入的基本用发
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Framework杂记
  • .net wcf memory gates checking failed
  • .NET 中创建支持集合初始化器的类型
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .net(C#)中String.Format如何使用
  • .Net8 Blazor 尝鲜
  • .NET的数据绑定
  • .net解析传过来的xml_DOM4J解析XML文件
  • @property python知乎_Python3基础之:property
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [ARM]ldr 和 adr 伪指令的区别