算法思想总结:二分查找算法

                                             创作不易,感谢三连!! 

一、二分查找算法思路总结

大家先看总结,然后再根据后面的题型去慢慢领悟

二、二分查找(easy)

. - 力扣(LeetCode)二分查找

思路:(模版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;
    }
};

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

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

 要注意示例3提到的边界情况!!

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

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target)
    {
        if(nums.size()==0)  return {-1,-1};//处理边界情况,否则会越界
        int begin=0;
        //区间左端点
           int left=0,right=nums.size()-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;
        //区间右端点
          right=nums.size()-1;
           while(left<right)
          {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<=target) left=mid;//最后会落在区间的右端点
            else right=mid-1;
          }
        return {begin,right};//此时至少有一个左端点,所以不可能找不到。
    }
};

四、x的平方根

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

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

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

 五、搜索插入位置

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

思路1:左端区间查找 

class Solution {
public:
    int searchInsert(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 right=mid;
        }
        if(nums[left]<target) return left+1;
        return left;
    }
};

思路2:右端区间查找(有特殊情况,比如正好是和targe相等且只有一个元素

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) 
    {
        int left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<target) left=mid;
            else right=mid-1;
        }
        //右端区间要考虑边界情况(特殊情况,只有一个元素且正好等于target)
        if(nums[left]>=target) return left;
        return left+1;
    }
};

 六、山峰数组峰顶的索引

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

本题特别的就是不再是升序,而是去找二段性的规律

思路1:左端区间查找 

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

思路2:右端区间查找 

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

七、寻找峰值

. - 力扣(LeetCode)寻找峰值

 左区间端点法:

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

右区间端点法:

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

 八、点名

. - 力扣(LeetCode)点名

左区间端点法 

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

注意:插入元素的时候要注意是否是在最右边插入!

九、 寻找旋转数组中的最小值

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

思路:左区间端点查找法

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

十、二分查找规律的再总结

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

  

     后面有遇到相关oj题博主会继续更新的……感谢支持!!

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

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

相关文章

基于 K8s 容器集群的容灾架构与方案

作者&#xff1a;庄宇 在设计系统架构时&#xff0c;我们必须假设任何组件和任何基础设施可能会在任何时间失效&#xff0c;例如&#xff1a;自然灾害&#xff0c;电力中断&#xff0c;网络中断&#xff0c;错误的系统变更等。为了应对挑战&#xff0c;我们必须设计合适的容灾…

COOH-PEG-Galactose 羧基-聚乙二醇-半乳糖 Galactose 靶向肝肿瘤细胞

在生物体内&#xff0c;正常细胞通过有氧呼吸将糖类等物质分解代谢产生能量&#xff0c;从而供给细胞的增殖和生 长。而癌细胞似乎更为“蛮横”&#xff0c;它们主要依靠糖酵解作用为生&#xff0c;因此癌细胞代谢葡萄糖的速度比正 常细胞要快得多。值得注意的是&#xff0c;…

Verilog——综合和防真

2.1综合 Verilog 是硬件描述语言&#xff0c;顾名思义&#xff0c;就是用代码的形式描述硬件的功能&#xff0c;最终在硬件电路上实 现该功能。在Verilog描述出硬件功能后需要使用综合器对Verilog代码进行解释并将代码转化成实际 的电路来表示&#xff0c;最终产生实际的电路&a…

PEG(2K)-g-[3.5]-PLL(20k)-g[3.5]-PEG(3.4k)-Biotin 生物素修饰聚乙二醇聚赖氨酸聚乙二醇

PEG-g-PLL-g-PEG-BIOTIN是一种生物素修饰的三嵌段共聚物。 PLL&#xff08;Poly-L-lysine&#xff09;是一种阳离子聚合物&#xff0c;由L-赖氨酸单体组成的聚合物。它具有多种应用&#xff0c;包括细胞培养、基因转染、组织工程和生物传感器等领域。 生物素可以与蛋白质亲和…

案例分析篇15:软件开发方法考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

[JAVAEE]—进程和多线程的认识

文章目录 什么是线程什么是进程进程的组成什么是pcb 进程概括线程线程与进程的关系线程的特点 创建线程创建线程方法创建线程的第二种方法对比 其他的方式匿名内部类创建线程匿名内部类创建Runable的子类lambda表达式创建一个线程 多线程的优势 什么是线程 什么是进程 首先想…

Java基础_内部类

文章目录 1.基本介绍1.定义&#xff1a;2.基本语法&#xff1a;3.内部类的分类 2.局部内部类1.快速入门2.局部内部类的使用 3.匿名内部类1.匿名内部类实现接口2.匿名内部类继承抽象类3.匿名内部类细节4.匿名内部类最佳实践1.匿名内部类作为实参传入函数2.匿名内部类课堂练习 4.…

一文浅谈射频识别RFID

RFID&#xff0c;全称为Radio Frequency Identification&#xff0c;即射频识别&#xff0c;是一种通过无线电信号识别特定目标并读取相关数据的技术。这种技术利用射频信号及其空间耦合、传输特性&#xff0c;实现对静止或移动物品的自动识别。 RFID由以下2个部分组成&#xf…

MongoDB从0到1:高效数据使用方法

MongoDB&#xff0c;作为一种流行的NoSQL数据库。从基础的文档存储到复杂的聚合查询&#xff0c;从索引优化到数据安全都有其独特之处。文末附MongoDB常用命令大全。 目录 1. 引言 MongoDB简介 MongoDB的优势和应用场景 2. 基础篇 安装和配置MongoDB MongoDB基本概念 使…

vue3.x项目,配置项目打包到二级目录

vue3.x项目&#xff0c;配置项目打包到二级目录 一、打开 vite.config.js 文件&#xff0c;添加或修改base字段&#xff0c; 将其值设置为二级目录的路径。例如想将应用部署到服务器上的/my-app目录下&#xff0c;如下设置&#xff1a; export default defineConfig({base: /…

滴滴 Flink 指标系统的架构设计与实践

毫不夸张地说&#xff0c;Flink 指标是洞察 Flink 任务健康状况的关键工具&#xff0c;它们如同 Flink 任务的眼睛一般至关重要。简而言之&#xff0c;这些指标可以被理解为滴滴数据开发平台实时运维系统的数据图谱。在实时计算领域&#xff0c;Flink 指标扮演着举足轻重的角色…

【C++基础】1.认识C++——《跟老吕学C++编程语言》

【C基础】1.认识C——《跟老吕学C编程语言》 认识CC简介C发展历程C四大特性支持数据封装和数据隐藏抽象支持继承和重用支持多态性 C语言工作原理C语言标准C标准库 认识C C简介 C&#xff0c;全称是C Plus Plus。老吕比较喜欢叫它C加加。 C是C语言的继承&#xff1b;C是是编译式…

(免费分享)基于springboot停车场管理平台(修复版)

修复百度车牌识别、修改样式、已知一些bug等 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 仅供学习交流&#xff0c;请勿随意传播&#xff0c;否则后果自负!! 角色&#xff1a; 超级…

Node.js入门基础—day01

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 初识node.js什…

【LeetCode热题100】73. 矩阵置零(矩阵)

一.题目要求 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 二.题目难度 中等 三.输入样例 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0…

python学习2:日志记录的用法

一些日志记录的简单记录&#xff1a; 用basicConfig可以进行配置 注意日志的等级&#xff1a; 上述代码得到的日志如下&#xff08;最基础的日志&#xff09;&#xff1a; 关于记录下来的日志格式可以有很多内容&#xff1a;如等级、发生的时间、发生的位置、发生的进程、…

《安富莱嵌入式周报》第334期:开源SEM扫描电子显微镜,自制编辑器并搭建嵌入式环境,免费产品设计审查服务,实用电子技术入门,USB资料汇总,UDS统一诊断

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1om411Z714/ 《安富莱嵌入式周报》第334期&#xff1a;开源SEM…

如何注册Devin-首个全自主AI软件工程师

最近devin大火&#xff0c;具体的就不说了&#xff0c;大家应该都知道&#xff0c;写代码非常nb&#xff0c;这里说一下devin的注册方式&#xff0c;目前devin的内测已经开启。 官网https://www.cognition-labs.com/blog注册网址Your reliable AI software engineerhttps://pr…

55. 跳跃游戏(力扣LeetCode)

文章目录 55. 跳跃游戏贪心每一次都更新最大的步数 取最大跳跃步数&#xff08;取最大覆盖范围&#xff09; 55. 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后…

【数理统计实验(三)】假设检验的R实现

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…