二分查找算法:穿越算法迷宫的指南

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

目录

前言

一.  二分查找算法介绍

二 二分查找的题目解析

2.1 二分查找

2.2 在排序数组中查找元素的第一个位置和最后一个位置

2.3 搜索插入位置 

2.4 x的平方根 

 2.5 山峰数组峰顶的索引

 2.6 寻找峰值

2.7 寻找旋转数组中的最小值 

2.8 点名 

 三. 二分算法总结+模板

总结


前言

本篇详细介绍了二分查找算法的使用,让使用者了解二分查找,而不是仅仅停留在表面, 文章可能出现错误,如有请在评论区指正,让我们一起交流,共同进步!


一.  二分查找算法介绍

二. 二分查找的题目解析

开始之前可以去总结部分被去看看模板,再结合题目理解

2.1 二分查找

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

 思路:(模版1)正常的二分查找策略

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

2.2 在排序数组中查找元素的第一个位置和最后一个位置

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

思路:找第一个,用左区间端点查找(模版2),找最后一个,用右端点区间查找(模版3) 

 

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        //处理边界情况
        if(nums.size() == 0) return {-1,-1};
        int left = 0;
        int right = nums.size()-1;
        int first = 0;
        //  1.二分左端点
        while(left<right)  //先找第一次的
        {
            int mid = (right - left)/2+left;
            if(nums[mid] >= target)
            {
                right = mid;
            }
            else
            {
                left = mid +1;
            }
        }
        //判断是否有结果
        if(nums[left] != target) return {-1,-1};
        else first = left;  //标记一下左端点
 
        //  2.二分右端点
        left = 0,right = nums.size()-1;
        while(left<right)
        {
            int mid = (right - left+1)/2+left;
            if(nums[mid] <= target)
            {
                left = mid;
            }
            else
            {
                right = mid -1;
            }
        }
        
        return {first,right};
    }
};

2.3 搜索插入位置 

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

 思路:左端区间查找 (右区间查找也行

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

2.4 x的平方根 

69. x 的平方根 - 力扣(LeetCode) 

思路:右端区间二分查找法 

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

 2.5 山峰数组峰顶的索引

852. 山脉数组的峰顶索引 - 力扣(LeetCode) 

思路:左或右端区间查找

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 1 ,right = arr.size()- 2;
        while(left < right)
        {
            int mid = (right - left + 1) / 2 + left;
            if(arr[mid]>arr[mid-1]) left = mid;
            else right = mid - 1;
        }
        return left;
    }
};

 2.6 寻找峰值

162. 寻找峰值 - 力扣(LeetCode) 

 思路:左或右端点区间查找

 右区间:

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

2.7 寻找旋转数组中的最小值 

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

思路:左区间端点查找法 

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

2.8 点名 

LCR 173. 点名 - 力扣(LeetCode)

 思路:左区间查找

class Solution {
public:
    int takeAttendance(vector<int>& records) {
        int left = 0, right = records.size()-1;
        while(left<right)
        {
            int mid = (right - left)/2+left;
            if(records[mid] == mid) left = mid + 1;
            else right = mid;
        }
        //处理细节问题:最后一个位置缺少
        return records[left] == left ? left+1 : left;
    }
};

 三. 二分算法总结+模板

二分查找的策略基本上都是去找一个数,对应的有三种模版:正常的二分查找、左区间端点查找、右区间端点查找。其中正常的二分查找局限性比较大,必须得是升序且限制条件较多,大多数情况下不符合题意。最常用的就是左区间端点(关键是left会大跳跃,且目标位置在较大值区间的左边)和右区间端点法(关键是right会大跳跃,且目标位置在较小值区间的右边)。 

图from:算法思想总结:二分查找算法-CSDN博客 


总结

✨✨✨各位读友,本篇分享到内容是否更好的让你理解二分查找算法,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TensorFlow图像识别项目

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 目录 今天我们将讨论如何部署Flask项…

【鸿蒙开发】HarmonyOS开发 URL动态路由设计

前言 2024 年是原生鸿蒙的关键一年&#xff0c;我们要加快推进各类鸿蒙原生应用的开发&#xff0c;集中打赢技术底座和三方生态两大最艰巨的战斗。余承东强调&#xff0c;要构建强大的鸿蒙生态&#xff0c;拉动中国电子工业崛起&#xff0c;开启终端未来大发展的新十年 。 去年…

c# 操作Microsoft Access数据库

数据库结构为&#xff1a; public static string connting "数据库路径&#xff1a;如&#xff1a;D:\\xxx.mdb";//插入public bool InsertToFile(string casenumber, int lastrowid, int pagecount){bool result true;try{string connString $"ProviderMicr…

零基础非科班也能掌握的C语言知识20 文件操作

文件操作 1.文件相关概念2.流和标准流2.1流2.2标准流 3.文件指针4.文件的打开关闭5.文件的顺序读写6.文件的随机读写6.1 fseek6.2 ftell6.3 rewind 7.⽂件读取结束的判定7.1 feof 8.文件缓冲区 1.文件相关概念 2.流和标准流 2.1流 我们程序的数据需要输出到各种外部设备&…

分层解耦

三层架构 controller:控制层&#xff0c;接收前端发送的请求&#xff0c;对请求进行处理&#xff0c;并响应数据&#xff0c; service:业务逻辑层&#xff0c;处理具体的业务逻辑。 dao:数据访问层(Data Access Object)(持久层)&#xff0c;负责数据访问操作&#xff0c;包括数…

Linux文件权限信息和Linux文件与文件夹的管理

目录 前言一、系统环境二、Linux文件权限信息2.1 查看Linux文件权限信息2.2 修改Linux文件权限信息2.2.1 chmod命令2.2.2 chown命令 三、Linux文件与目录的管理3.1 查看文件或文件夹3.1.1 查看文件内容3.1.2 查看文件夹内容 3.2 新增文件或文件夹3.2.1 新增文件3.2.2 新增文件夹…

Node.js版本管理工具-NVM

在开发 Node.js 项目时&#xff0c;经常会遇到需要切换不同版本的 Node.js 的情况。为了方便管理和切换各个版本&#xff0c;我们可以使用一些 Node.js 版本管理工具。 Node Version Manager&#xff1a;简称NVM&#xff0c;最流行的 Node.js 版本管理工具之一。它允许我们在同…

C++---模板进阶(非类型模板参数,模板的特化,模板分离编译)

我们都学习和使用过模板&#xff0c;而这篇文章我们来将一些更深入的知识。在此之前&#xff0c;我们在使用C编程时可以看到模板是随处可见的&#xff0c;它能支持泛型编程。模板包括函数模板和类模板&#xff0c;我们有的人可能会说是模板函数和模板类&#xff0c;但严格讲这样…

【话题】评价GPT-4o:从革命性技术到未来挑战

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 引言技术原理应用领域实际案例优势挑战局限性未来展望文章推荐 引言 在人工智能领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术的进步一直是推动技术革…

Allegro蛇形等长

Allegro蛇形等长 一、蛇形等长规则创建方法 一般有点对点&#xff0c;串组两种形式 点对点一般直接在规则中建立等长组 串组可以用模型等长和pin to pin等长 下面提供pin to pin的方法&#xff0c;个人感觉最好用 二、创建规则 打开规则管理器&#xff0c;展开Electrical–…

Studio One安装教程+软件安装包下载

Studio One6全新版本上线 记录、生产、混合、掌握和执行所有操作。从工作室到舞台&#xff0c;Studio One6以易用为核心&#xff0c;是您的创意合作伙伴。 当你准备好登上舞台时&#xff0c;Studio One就在那里。只有Studio One从最初的灵感到完整的制作&#xff0c;最终混音…

【STM32】基于I2C协议的OLED显示(利用U82G库)

【STM32】基于I2C协议的OLED显示(利用U82G库) 文章目录 【STM32】基于I2C协议的OLED显示(利用U82G库)一、实验背景二、U8g2介绍&#xff08;一&#xff09;获取&#xff08;二&#xff09;简介 三、实践&#xff08;一&#xff09;CubexMX配置&#xff08;二&#xff09;U8g2配…

官方正版 | Mailbird - 2024 年最佳电子邮件客户端

Mailbird&#xff1a;个性化的电子邮件客户端 Mailbird 是一款专为 Windows 用户设计的桌面电子邮件客户端&#xff0c;以其用户友好的界面和强大的功能获得了广泛好评。以下是 Mailbird 的主要特点&#xff1a; 个性化背景&#xff1a;Mailbird 提供了可定制的背景选项&#…

【Qt 学习笔记】Qt窗口 | 标准对话框 | 消息对话框QMessageBox

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | 标准对话框 | 消息对话框QMessageBox 文章编号&#xff1a;Q…

linux pxe和无人值守

一 PXE和无人值守 pxe c/s模式 允许客户端通过网络从远程服务器&#xff08;服务端&#xff09;下载引导镜像 加载安装文件 实现自动化安装操作系统 无人值守 就是安装选项不需要认为干预 可以自动化实现 pxe的优点 1 规模化 同时装配多台服务器 20多 30台 2 自动化 …

Rust学习06:使用CSDN的AI工具“C知道”分析代码错误

朋友们&#xff0c;我最近真的是在绝望的边缘了&#xff01; Rust咋这么蓝涅&#xff01; 资料咋这们少涅&#xff01; 记得学Python的时候&#xff0c;基本上你遇到的所有问题都可以在书上或者网上找到答案&#xff0c;中文世界找不到那么在英文世界一定能找到答案。 我猜&…

Redis】Redis主从复制(二)————主从结构/流程

目录 回顾slaveof 命令断开主从复制关系切换主从复制关系只读网络延迟问题应对措施补充 主从结构一主一从结构问题改进 一主多从结构树形主从主从切换结构 主从复制流程简单来记关于数据同步两个参数replicationidoffset. psync 运行流程全量复制和部分复制全量复制流程&#x…

使用使用rundll32 调用指定dll的方法

使用使用rundll32 调用指定dll的方法 //顾名思义&#xff0c;"执行32位的DLL文件"。它的作用是执行DLL文件中的内部函数&#xff0c;这样在进程当中&#xff0c; 只会有Rundll32.exe&#xff0c;而不会有DLL后门的进程&#xff0c;这样&#xff0c;就实现了进程上的隐…

自定义组件——ABManager(AB包管理器)

需求描述 在Unity3D引擎中&#xff0c;AB包作为常用的游戏资源存储格式之一。而对于资源管理我们就不得不谈到集中管理的优势了&#xff0c;通过统一的接口加载和卸载AB包及其中的资源将进一步提升我们的编程效率。本文将围绕这个需求进行尝试。 功能描述 1. AB包的加载包括同…

项目:双人五子棋对战-对战模块(6)

完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com 当玩家进入到游戏房间后, 就要开始一局紧张而又刺激的五子棋对战了, 本文将就前端后端的落子与判断胜负的部分作详细讲解. 模块详细讲解 约定前后端交互的接口 首先是建立连接后, 服务器需要生成一些游戏的初始信息(可…