二分查找(my理解和模板)

简介: 之前先学了y总的二分,后来又看了代码随想录的,感觉代码随想录的更好记忆

之前先学了y总的二分,后来又看了代码随想录的,感觉代码随想录的更好记忆

二分查找需要的数据必须是有序的。如果数据没有序,我们需要先排序,排序的时间复杂度最低是 O(nlogn)。

二分查找底层依赖的是数组,数组需要的是一段连续的存储空间,所以数据量太大不适合二分查找

查找的方法,顾名思义,就是若 target = arr[mid],则查找成功(找到了目标值)返回 mid 值

🚥🚥🚥

根据check()来划分区间

🚥🚥🚥

⭐整数二分

划分为[l,mid]和[mid+1,r]  

int binary(int l,int r){
  while(l<r){
    int mid=(l+r)/2;
    if(check(mid)) r=mid;
    else l=mid+1;
  }
  return l;
}

划分为[l.mid-1]和[mid,r]

int binary(int l,int r){
  while(l<r){
    int mid=(l+r+1)/2;
    if(check(mid)) l=mid;//如果先是l=mid,那么为(l+r+1).要+1
    else r=mid+1;
  }
  return l;
}

浮点数二分

int binary(int l,int r){
  while(l-r>0.001){ //0.001可以又其他浮点数代替,但是都必须尽可能小
    int mid=(l+r)/2;
    if(check(mid)) r=mid;//l=mid
    else l=mid;          //r=mid
  }                        //根据check()决定
  return l;
}

35. 搜索插入位置 - 力扣(LeetCode)

1.1.png

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
       int l=0,r=nums.size();
       while(l<r)
       {
           int mid=(l+r)/2;
           if(nums[mid]>target) r=mid;
           else if(nums[mid]<target) l=mid+1;
           else
           return mid;
       }
       return l;
    }
};

P1024 [NOIP2001 提高组] 一元三次方程求解 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.2.png

#include<cstdio>
double a,b,c,d;
double fc(double x)
{
    return a*x*x*x+b*x*x+c*x+d;
}
int main()
{
    double l,r,mid,x1,x2;
    int s=0,i;
    scanf("%lf%lf%lf%lf",&a,&b,&c,&d);  
    for (i=-100;i<100;i++)
    {
        l=i; 
        r=i+1;
        x1=fc(l); 
        x2=fc(r);
        if(!x1) 
        {
            printf("%.2lf ",l); 
            s++;
        }      //判断左端点,是零点直接输出。
                        //不能判断右端点,会重复。
        if(x1*x2<0)  //区间内有根。
        {
            while(r-l>=0.001)  //二分控制精度。
            {
                mid=(l+r)/2;  
                if(fc(mid)*fc(r)<=0) 
                   l=mid; 
                else 
                   r=mid;   //计算中点处函数值缩小区间。
            }
            printf("%.2lf ",r);  
            //输出右端点。
            s++;
        }
        if (s==3) //每找到一个,s++,当s=3时,就找到了3个
            break;             
    }
    return 0;
}

下面这个题可以体会到check()选择区间的条件

789. 数的范围 - AcWing题库

得用两次二分,找到左右两个值

1.3.png

#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int q[N];
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
    while (m -- )
    {
        int x;
        scanf("%d", &x);
        int l = 0, r = n - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (q[mid] >= x) r = mid;//>=x
            else l = mid + 1;
        }
        if (q[l] != x) cout << "-1 -1" << endl;
        else
        {
            cout << l << ' ';
            int l = 0, r = n - 1;
            while (l < r)
            {
                int mid = l + r + 1 >> 1;
                if (q[mid] <= x) l = mid;//<=x
                else r = mid - 1;
            }
            cout << l << endl;
        }
    }
    return 0;
}

P8647 [蓝桥杯 2017 省 AB] 分巧克力 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1.4.png

建议听听这个视频讲解http://【P8647 [蓝桥杯 2017 省 AB] 分巧克力】https://www.bilibili.com/video/BV1sx4y1L7Xq?vd_source=21581d752de8daca00ef38561a7264f6

或者

AcWing 1227. 分巧克力(寒假每日一题) - AcWing  


image.pngimage.png

image.png

注意是长和宽,得开二维数组

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, k;
int h[N], w[N];
bool check(int mid)
{
    int res = 0;
    for (int i = 0; i < n; i ++ )
    {
        res += (h[i] / mid) * (w[i] / mid);
        if (res >= k) return true;
    }
    return false;
}
int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i ++ ) scanf("%d%d", &h[i], &w[i]);
    int l = 1, r = 1e5;
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    printf("%d\n", r);
    return 0;
}

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
供应链 数据可视化 JavaScript
60种常用可视化图表的使用场景——(上)
60种常用可视化图表的使用场景——(上)
409 0
|
自然语言处理 算法 数据可视化
NLP-基于bertopic工具的新闻文本分析与挖掘
这篇文章介绍了如何使用Bertopic工具进行新闻文本分析与挖掘,包括安装Bertopic库、加载和预处理数据集、建立并训练主题模型、评估模型性能、分类新闻标题、调优聚类结果的详细步骤和方法。
NLP-基于bertopic工具的新闻文本分析与挖掘
|
存储 人工智能 数据管理
如何借助AI技术为NAS注入新活力
【8月更文挑战第11天】文件存储NAS是高性能、可共享访问的分布式文件系统,支持弹性扩展与高可靠性。通过融合AI技术,NAS能在数据存储路径上实现最优规划,提升存储效率;借助AI自学习能力优化数据管理流程;并实现精准的数据共享,最大化数据价值。
如何借助AI技术为NAS注入新活力
|
图形学 开发者
U3D开发进阶:精细调整Collider与优化碰撞检测性能
【7月更文第11天】在Unity 3D(简称U3D)开发过程中,精确控制Collider(碰撞器)的设置与合理利用Layer Collision Matrix(层级碰撞矩阵)对于提升游戏性能、优化物理模拟至关重要。本文将深入探讨这两项技术的应用,通过实际案例和代码示例,帮助开发者构建更加高效、流畅的游戏体验。
2143 2
|
SQL 存储 数据采集
数据库审计的四种类型
【7月更文挑战第11天】企业在互联网时代认识到数据的核心价值,尤其对审计方法提出了新挑战。
|
存储 缓存 监控
Java面试题:解释堆和栈的OutOfMemoryError通常在什么情况下会发生
Java面试题:解释堆和栈的OutOfMemoryError通常在什么情况下会发生
219 3
|
存储 调度 Apache
airflow scheduler 这些命令是什么作用
【6月更文挑战第30天】airflow scheduler 这些命令是什么作用
264 0
|
网络协议 Linux API
c++网络库Libevent万字详解
libevent和libev都是c语言实现的异步事件库;通过注册异步事件,库检测事件触发,从而库根据发生事件的先后顺序,调用相应回调函数进行处理;事件包括:网络io事件,定时事件,信号事件;事件循环:等待并分发事件;用于管理事件;libevent 和 libev 主要封装了异步事件库与操作系统的交互;让用户不用关注平台的差异,只需着手事件的具体处理;创建事件处理框架event_base event_base_new()创建新事件event event_new()
655 0
|
小程序 Android开发
(成功最详细版本,自定义传参失败,跳转出现空白页面,校验文件失败)微信小程序扫码跳转小程序指定页面保姆级教程
文档里面虽然说了,但是还是有几个坑的地方,坑等文章最后面再写扫普通链接二维码打开小程序 | 微信开放文档
917 0
(成功最详细版本,自定义传参失败,跳转出现空白页面,校验文件失败)微信小程序扫码跳转小程序指定页面保姆级教程
|
存储 分布式计算 算法
《全链路数据治理-智能数据建模 》——客户案例:汽车行业数据建模最佳实践(4)
《全链路数据治理-智能数据建模 》——客户案例:汽车行业数据建模最佳实践(4)
585 0

热门文章

最新文章