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

【C++算法】二分查找 -> 入门

二分,我********

二分查找的介绍

二分查找的特点

在二分查找中,它是最恶心,细节最多,最容易写出死循环的算法,但是只要我们把它弄清楚,去理解,最恶心就会变得最简单了

学习中的侧重点

1、算法原理

使用二分查找,不止可以在数组有序得情况去使用,在我们理解的深刻,那么我们也可以发现一些规律,即使在数组无序中,我们也可以去使用二分优化

2、模板

我们学习二分,一定要去理解模板,不要去死记硬背,理解之后再去记忆,才能发挥最大的功能!

二分查找模板一共有3个:

朴素的二分模板虽然比较简单,但是它有一定的局限性,左边界和右边界其实也算我们的万能模板

开始学习!

一、二、三,上链接!

704. 二分查找 - 力扣(LeetCode)

(一)朴素的二分模板

二分查找算法原理:

1.二分查找算法的本质是利用数组的有序性和二段性进行高效搜索。

2.二段性:通过比较中间元素,将数组分成两个子数组,根据比较结果舍去一部分,继续在另一部分搜索。

3.适用范围:不仅限于有序数组,只要满足二段性即可。

二段性,就是分半,mid = left + (right - left)/2;

例如:在一堆数组,我们要找target

1、如果这个数组,比5小的,也就是1~4,不是我们的目标值,我们是不是可以舍去?答案是的

目标值在5~7的区间里

2、继续搜,是不是如果比5大的,我们也不要呢?答案是的

3、在搜索,如果mid == target,此时这个就是我们的答案,可以直接返回了

最后,为什么可以不要这些值?因为他不是我们需要的值呀,人家要找5,你搜6和7的区间有个屁用?

二分查找算法细节问题:

1.定义left和right指针,初始化搜索区间。

2.循环条件:left <= right。

3.在循环中,计算中间元素的索引mid,并与目标值进行比较。

4.根据比较结果更新left或right指针,缩小搜索区间。

5.如果找到目标元素,返回其索引;如果未找到,返回-1。

class Solution { public: int search(vector<int>& nums, int target) { int left = 0, right = nums.size() - 1; while(left <= right) { int mid = left + (right - left) / 2;//防止溢出 if(nums[mid] < target) left = mid + 1; else if(nums[mid] > target) right = mid - 1; else return mid; } return -1; } };

mid,为什么这样子写?

int left = 2,000,000,000; // 20亿 int right = 2,000,000,000; // 20亿 int mid = (left + right) / 2; // left + right = 40亿 ❌ 超过 int 最大值 21.47亿!
left = 1,500,000,000 right = 2,000,000,000 right - left = 500,000,000 // ✅ 差值很小,不会溢出 mid = 1,500,000,000 + 250,000,000 = 1,750,000,000 // ✅ 正确

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

(二)查找左边界的二分模板

我们找7,第一个出现的7

为什么r要等于mid?

这仅适用于arr[mid] > target的情况(mid 值已大于 target,mid 及其右边都不可能等于 target)。但如果arr[mid] == target,mid 可能是答案,不能r=mid-1,而应r=mid保留 mid。

为什么l要等于mid+1?

如果arr[mid] < target,整个[l, mid]区间都小于 target,不可能有答案,所以应l = mid+1(排除)。如果arr[mid] >= target,答案可能在[l, mid],此时不是l=mid,而是r=mid(向左收缩)。

(三)查找右边界的二分模板

同理:

l=mid

  • arr[mid] <= target:mid 及其左边都可能 ≤ target,但我们想要最右边的,所以答案可能在[mid, r]区间(因为 mid 可能就是答案,也可能右边还有)。此时应保留 mid,收缩左边界:l = mid

r=mid

  • arr[mid] > target:mid 的值已经大于 target,那么 mid 及其右边都肯定不是答案,直接排除:r = mid - 1

细节讨论:

循环条件:

left < right √

  1. 当left == right的时候,就是最终结果
  2. 如果判断容易造成死循环

中点位置:

left + (right - left) / 2左中位数(偏左)

left + (right - left + 1) / 2右中位数(偏右)

看一个极端例子:left=0, right=1

  • 如果找最后一个,逻辑是if (arr[mid] <= target) l = mid;

    • 用公式①(偏左,mid=0)→l = 0,区间[0,1]没变,死循环

    • 用公式②(偏右,mid=1)→l = 1,区间变为[1,1]正常退出

  • 如果找第一个,逻辑是if (arr[mid] >= target) r = mid;

    • 用公式②(偏右,mid=1)→r = 1,区间[0,1]没变,死循环

    • 用公式①(偏左,mid=0)→r = 0,区间变为[0,0]正常退出

题目ac代码:

class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { if(nums.size()==0)return {-1,-1}; int begin=0; // 1、找左端点 int l=0,r=nums.size()-1; while(l<r) { int mid=l+(r-l)/2; if(nums[mid]<target) { l=mid+1; }else { r=mid; } } if(nums[l] != target) return {-1,-1}; else begin=l; // 2、找右端点 l=0,r=nums.size()-1; while(l<r) { int mid=l+(r-l+1)/2; if(nums[mid]<=target) { l=mid; }else{ r=mid-1; } } return {begin,r}; } };

总结模板:

http://www.jsqmd.com/news/1379777/

相关文章:

  • 2026 企业级地址解析服务商选型指南
  • 基于OIDC实现GitHub Actions免密安全部署至阿里云OSS
  • 3步搞定抖音无水印下载:开源douyin_downloader工具终极指南
  • 数据血缘落地实战:从技术选型到运营闭环的完整指南
  • 2026年最新测厚仪/电磁超声检测设备/脉冲涡流检测设备生产厂家核心竞争力解构 - 青岛科瑞富有潜力 - 小范同学a
  • 手把手教你学 Simulink—— 基于扩展卡尔曼滤波(EKF)的整流器状态估计与故障预测仿真
  • 当 human in the loop 变成“闭着眼睛点确认”,企业Agent 安全还能靠谁?
  • 爬虫怎么批量采集完成任务
  • NS-Scope:释放泰克TDS示波器潜力,实现高精度数据采集与自动化测试
  • 500元预算下的AI工具栈实战:Serverless与LLM API低成本应用指南
  • MFC开发实战:CZip与CUnzip类实现ZIP文件压缩解压
  • 游戏资源逆向工程:从解包到4K渲染的技术实践与美术资产分析
  • 2026 涂胶机厂家推荐哪家好?高口碑品牌汇总 - 商业新知
  • C++ enable_shared_from_this 原理详解与安全使用指南
  • 用身份证二要素核验接口过一道真人关(C# 实战)
  • 多专家辩论复盘法:突破单一视角,提升决策质量
  • 2026年苏州无锡打印机租赁与复印机维修,设备故障怎么处理? - LYL仔仔
  • 【拯救HMI】:自动化对外输出的壁垒突破:标准认证与技术适配的双重路径
  • 为什么显卡内存检测如此重要?memtest_vulkan为你揭示硬件真相
  • 一个 NoSuchMethodError 查了 4 小时:双亲委派‘先问爹’的机制,让新 jar 永远赢不了老 jar
  • 软件开发工程化 · 体系篇:工程化的五个维度——从规范到交付
  • 落地还原度实测:2026杭州3家别墅装修服务商对比报告 - 互联网科技品牌测评
  • C语言控制结构原理与性能优化实战
  • RedisDesktopManager Windows版:告别命令行,5分钟开启Redis可视化管理新时代
  • 车载以太网(2)-davinci之ARP协议
  • Xγ剂量率仪国产厂家推荐|恒美智造辐射巡检仪国内头部品牌盘点 - 专业仪器测评品牌推荐
  • SolidWorks自定义焊件轮廓:从原理到实战,提升非标设计效率
  • 解决Windows系统computelibeventlog.dll丢失问题的完整指南
  • 一团乱麻?带你厘清 Rust 中的函数指针、函数项、fn 类型、Fn Trait
  • ECharts GL 3D地图开发实战:从环境搭建到性能优化