【算法】深入理解二分查找算法及其应用

文章目录

  • 1. 朴素二分查找的基本步骤:
  • 2. 总结二分模板

二分查找(Binary Search)是一种在有序数组中查找目标值的高效算法。它的基本思想是将数组分成两半,然后确定目标值可能存在的那一半,重复这个过程直到找到目标值或者确定目标值不存在为止。

1. 朴素二分查找的基本步骤:

  1. 初始化左右边界:将左边界 left 初始化为数组的起始位置,将右边界 right 初始化为数组的结束位置。
  2. 循环直到左边界小于等于右边界:
  • 计算中间位置 midmid = (left + right) / 2。
  • 如果目标值等于中间位置的值,则返回中间位置。
  • 如果目标值小于中间位置的值,则将右边界移到 mid - 1
  • 如果目标值大于中间位置的值,则将左边界移到 mid + 1
  1. 如果循环结束时仍未找到目标值,则返回不存在的标记(例如 -1)。
    二分查找的时间复杂度为 O(log n),其中 n 为数组的长度。这是因为在每一次迭代中,搜索范围都会减半,直到找到目标值或者搜索范围缩小到零为止。因此,二分查找在大型有序数组中查找目标值时非常高效。

eg1: 最朴素的二分查找
在这里插入图片描述

class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size(); // 初始化 left 与 right 指针int left = 0, right = n-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;}}// 如果程序⾛到这⾥,说明没有找到⽬标值,返回 -1return -1;}
};

eg2: 在排序数组中查找元素的第⼀个和最后⼀个位置
在这里插入图片描述

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int n = nums.size(), begin, end;if (n == 0) return{-1, -1};// 1. 查找区间左端点int left = 0, right = n-1;while (left < right) {int mid = left + (right-left)/2;if (nums[mid] < target) left = mid + 1;else right = mid;}// 判断是否有结果if (nums[left] != target) return{-1, -1};else begin = left; // 标记一下左端点// 2. 查找区间右端点left = 0, right = n-1;while (left < right) {int mid = left + (right-left+1)/2;if (nums[mid] <= target) left = mid;else right = mid-1;}end = right;return{begin, end};}
};

2. 总结二分模板

查找区间左端点的模板:

while (left < right) {int mid = left + (right - left) / 2;if (/* 检查目标值是否满足条件 */) {left = mid + 1;} else {right = mid;}
}
查找区

查找区间的右端点的模板

while (left < right) {int mid = left + (right - left + 1) / 2;if (/* 检查目标值是否满足条件 */) {left = mid;} else {right = mid - 1;}
}

助记:让下面出现-1的时候,上面就+1。

eg3: 搜索插⼊位置
在这里插入图片描述

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int n = nums.size();int left = 0, right = n-1;// 找到区间左端点while (left < right) {int mid = left + (right-left)/2;if (nums[mid] < target) left = mid+1;else right = mid;}if (nums[left] < target) return right+1;else return right;}
};

eg4: x 的平⽅根
在这里插入图片描述

class Solution {
public:int mySqrt(int x) {if (x < 1) return 0; // 处理边界情况int left = 0, right = x;while (left < right) {long long mid = left + (right-left+1)/2; // 用long long mid*mid防止溢出if (mid*mid <= x) left = mid;else right = mid-1;}return left;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/624457.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

试用模方时,系统一直提示“未找到有效配置文件” ,是需要安装3dsmax吗 ?

问题如图 把文件放在认证管理服务安装目录下即可。&#xff08;注&#xff1a;因平台限制&#xff0c;需要文件的直接后台私信即可哦&#xff09; 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件…

Android studio顶部‘app‘红叉- Moudle ‘XX.app’ dosen’t exist in project

Android studio顶部app红叉- Moudle ‘XX.app’ dosen’t exist in project 1、现象&#xff1a; 运行老项目或者有时候替换项目中的部分代码&#xff0c;明明没有错但是Android studio就编译报错了。 1.1 Android studio顶部app红叉。 1.2 点击Build没有clear菜单&#xff0…

CANoe中LIN工程主节点的配置(如何切换调度表)

1&#xff1a;前置条件 1&#xff09;工程已经建立&#xff0c;simulation窗口已经配置好&#xff08;包括且不限于通道mappin好&#xff0c;数据库文件已经添加&#xff09; 2&#xff09;我已系统自带sampleCfg工程&#xff0c;作为例子。如下图 2 &#xff1a;主节点的配置…

每日一题(PTAL2-006):树的遍历--树的构建,队列

因为要层序遍历&#xff0c;所以我们可以考虑构建一颗二叉树。构建完只有利用队列就可以就行层序遍历。 #include <bits/stdc.h> using namespace std; int p1[35]; int p2[35]; typedef struct Tree {int val;struct Tree* left;struct Tree* right; }TT; typedef TT* …

C# 两种方法截取活动窗口屏幕,实现窗体截图

方法1&#xff0c;截屏内容仅包括活动窗口界面&#xff0c;而方法2是从屏幕范围取图&#xff0c;截屏内容会包括屏幕上所有内容。例如有一些程序在桌面顶层显示半透明的悬浮窗&#xff0c;用方法2截屏就会包括这些内容&#xff0c;并不是单纯的活动窗口内容。 方法1&#xff0c…

bdf文件导入事件错误情况

先打开脑电再导入事件 数据情况

ChatGPT深度科研应用、数据分析及机器学习、AI绘图与高效论文撰写教程

原文链接&#xff1a;ChatGPT深度科研应用、数据分析及机器学习、AI绘图与高效论文撰写教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601506&idx2&sn5dae3fdc3e188e81b8a6142c5ab8c994&chksmfa820c85cdf58593356482880998fc6eb98e6889b261bf62…

docker拉取镜像速度慢

解决办法是配置阿里云镜像加速 在docker desktop的docker engine里添加 "registry-mirrors": ["https://owzy8hoh.mirror.aliyuncs.com"] 修改以后重启docker 参考&#xff1a; 【docker】Windows10系统下安装并配置阿里云镜像加速_docker desktop 配置…

Hyperledger Fabric

一.Hyperledger Fabric介绍 Hyperledger区块链全家桶 Hyperledger Fabric技术特性 资产 — 资产定义使得几乎任何具有货币价值的东西都可以在网络上交 换&#xff0c;包括从食品到古董汽车再到货币期货。链码 — 链码执行与交易排序的分离&#xff0c;限制了跨节点类型所需的…

vue3: 报错ResizeObserver loop completed with undelivered notifications.解决方法

错误提示&#xff1a; 组件重新绘制大小时dev环境出现报错提示&#xff0c;如在VUE3中使用ant-design-vue表格自适应窗口大小时webpack会报错。 常用解决方案有重写ResizeObserver或者时间间隔内限制执行方式&#xff0c;可以设置屏蔽方式跳过提示。 解决办法&#xff1a; 修…

保姆级教程 | Adobe Illustrator 中插入数学符号

背景 鉴于Adobe Illustrator作为比较专业的绘图/组图软件&#xff0c;我的论文数据作图都会选择先在origin中把原始数据绘制好&#xff0c;后都放入AI中细修。由于在作图过程中需要插入数学符号&#xff0c;但仿佛没有PowerPoint用起来那么熟悉&#xff0c;遂记录下。 步骤 …

HTML 入门

HTML 简介 1. 什么是 HTML&#xff1f; 全称&#xff1a;HyperText Markup Language&#xff08;超文本标记语言&#xff09;。 超文本&#xff1a;暂且简单理解为 “超级的文本”&#xff0c;和普通文本比&#xff0c;内容更丰富。 标 记&#xff1a;文本要变成超文本&…