二分查找的模板

news2024/11/25 7:05:36

这篇博客的二分用的都是左闭右闭的区间,对于二分来说还是我还是习惯这样写

最传统的二分查找,用左闭右闭写

  int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }

左闭右开来写,注意的就是当中间值大于目标值的时候,right可不是mid-1,而是mid,因为右边是开的

 int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在[middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }

用二分去找目标值的左边界和右边界的问题,当然我们可以去先普通二分找到目标值,再在这个目标值的位置开始左右去线性探测找左右边界,但是当目标值重复太多,你这么写二分就不是二分了,不就是On线性去找

所以这里写的都是纯二分的思路,还是用左闭右闭去写,好好体会代码逻辑

左边界里我多定义一个变量去表示,整体代码和右边界可能会有一丢丢出入(右边界的看着简单),但是俩逻辑都是一模一样,就是写的方式不同,都看懂了才能明白这个怎么去找边界

先放两张图去体会一下,什么是二分找边界。这题是力扣34. 在排序数组中查找元素的第一个和最后一个位置,我分开写去分别表示左边界和右边界

 

找左边界的模板代码

 int getLeftBorder(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
        while (left <= right) {
            int middle = left + ((right - left) / 2);
            if (nums[middle] >target) { // 寻找左边界,nums[middle] == target的时候更新right
                right = middle - 1;
               
            } else if(nums[middle] <target){
                left = middle + 1;
            }
            else if(nums[middle] ==target)
            {         
                leftBorder = middle;  
                right = middle - 1;
            }
        }
        return leftBorder;
    }

 找右边界的模板代码,俩其实都能改成一样的

  int getRightBorder(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
 
        while (left <= right) {
            int middle = left + ((right - left) / 2);
            if (nums[middle] > target)
            {
                right = middle - 1;
            } 
            else if(nums[middle] <= target)
            { // 寻找右边界,nums[middle] == target的时候更新left
                        
                left = middle + 1;  
            }               
        }
        return right;
    }

 今天的记录就到这了..2022/11/10

 希望努力会有回报

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis学习之动态Sql

目录 1. 什么是动态Sql 2. 动态Sql需要学习什么 3. 动态Sql之《if》 4. 动态Sql之《where》 5. 动态Sql之《foreach》 6. 动态Sql之《sql》 7. PageHelper分页插件的使用 1. 什么是动态Sql 答案&#xff1a;动态Sql指的是&#xff0c;Sql语句是变化的&#xff0c;不是固…

Allegro原理图反标教程

Allegro原理图反标教程 Logic→Auto Rename Refdes→Rename 点击More进行详细设置 按照下图设置 点击Rename 打开刚刚rename时生成的rename.log文件,需要提取一些数据,如下图 将上图所有带有OLD和NEW的行提取出来,再将OLD,NEW删除 打开Capture,点击Tools→Back Annota…

C++中运行一个程序的内存分配情况及qt中的内存管理机制

一个由c/C编译的程序占用的内存分为以下几个部分 1、栈区&#xff08;stack&#xff09;— 由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区&#xff08;heap&#xff09; — 一般由程序员分配释放&a…

【springboot】你了解@Autowired 和 @Resource吗?@Autowired 和 @Resource深入分析

Autowired 和 Resource深入分析“认祖归宗”--Autowired 和 Resource来源“通过现象看本质”--Autowired 和 Resource作用和区别1.现象一&#xff1a;一个业务接口只对应一个业务实现类2.现象二&#xff1a;一个业务接口 对应 两个或多个业务实现类我们在开发中&#xff0c;一直…

【数据结构】链表其实并不难 —— 手把手带你实现双向链表

文章目录0. 前言1. 双向链表的概念2. 双向链表的实现2.1 结构设计2.2 接口总览2.3 初始化2.4 创建新节点2.5 尾插2.6 头插2.7 尾删2.8 头删2.9 查找2.10 在pos位置之前插入2.11 在pos位置删除2.12 打印2.13 销毁3. 完整代码List.hList.ctest.c4. 结语0. 前言 之前&#xff0c;…

【Python百日进阶-WEB开发】Day175 - Django案例:07状态保持

文章目录五、状态保持5.1 Django中状态保持5.1.1 状态保持概述5.1.2 Cookie5.1.2.1 Cookie的用处&#xff1a;5.1.2.1 Cookie的特点&#xff1a;5.1.2.1 Cookie的操作&#xff1a;5.1.3 session5.1.3.1 Session的特点&#xff1a;5.1.3.2 Session依赖于Cookie5.1.3.3 存储方式5…

网页数据抓取-网页实时数据抓取软件

网页数据抓取&#xff0c;随着社会的发展&#xff0c;互联网的普及&#xff0c;不管是企业还是个人都意识到数据的重要性。今天给大家分享一款免费的网页数据抓取软件。只要点点鼠标就能轻松采集你想要的内容不管是导出还是自动发布都支持&#xff01;详细参考图片&#xff01;…

Qlib股票数据获取与查看(Qlib学习1)

文章目录Qlib基本信息数据使用方法1. 借助Qlib下载数据2. 查看相关数据参考链接Qlib基本信息 Qlib Github主页&#xff1a;https://github.com/microsoft/qlib Qlib quickstart&#xff1a;https://qlib.readthedocs.io/en/latest/introduction/quick.html#introduction 基本…

LeetCode刷题---142. 环形链表 II(双指针-快慢指针)

文章目录一、编程题&#xff1a;142. 环形链表 II&#xff08;双指针-快慢指针&#xff09;1.题目描述2.示例1&#xff1a;3.示例2&#xff1a;4.示例3&#xff1a;5.提示&#xff1a;6.提示&#xff1a;二、解题思路1.思路2.复杂度分析&#xff1a;3.算法图解三、代码实现总结…

如何理解Linux下一切皆文件

文章目录一、问题抛出二、如何理解三、Linux源码验证一、问题抛出 Linux中普通文件、目录、字符设备、块设备、网络设备等都被当做文件来对待。虽然他们的类型不同&#xff0c;但是Linux中提供了统一的操作接口。  普通文件、目录文件显然非常好理解&#xff0c;因此在本文中&…

今日论文阅读2022-11-10

多模态预训练论文ViLBERT: Pretraining Task-Agnostic Visiolinguistic Representations for Vision-and-Language Tasksvision-and-language tasks&#xff1a; visual question answering,visual commonsense reasoning, referring expressions, and caption-based image ret…

基于DeepLabV3实践路面、桥梁、基建裂缝裂痕分割

在我前面的文章中有基于改进的模型开发的裂缝裂痕检测模型&#xff0c;感兴趣的话可以看下&#xff1a; 《基于yolov5sbifpn实践隧道裂缝裂痕检测》 今天主要是趁着有时间基于deeplabv3来实践裂缝裂痕分割。首先来看效果图&#xff1a; 为了整体直观&#xff0c;这里专门是开…

腾讯蓝鲸 API 网关如何借助 APISIX 实现产品升级与业务完善

分享嘉宾朱雷&#xff0c;腾讯 IEG 运维 PaaS 平台技术负责人。 蓝鲸&#xff08;全名“蓝鲸智云”&#xff09;是一套孵化于腾讯 IEG&#xff08;互动娱乐事业群&#xff09;内部&#xff0c;服务于多业务与各内部平台的研运一体化 PaaS。 其作用是在 CI、CD 和 CO 三个阶段&a…

Spring 概述

Spring是 Java 应用程序开发框架。 Spring 框架的目标是使 J2EE 开发变得更容易使用&#xff0c;通过启用基于 POJO编程模型来促进良好的编程实践。 Spring Framework Spring 基础框架是 Spring Framework &#xff0c;基本上任何其他 Spring 项目都是以 Spring Framework 为…

如何进入 mysql?

目录 1. win r 2. 输入cmd点确定 3. 输入 mysql -u -t 4. 点回车出现 下面的 就代表已经进入 mysql 退出 mysql的 方法&#xff1a; 1. win r 2. 输入cmd点确定 3. 输入 mysql -u -t -u &#xff1a;代表你的用户名&#xff0c;如果是本地登录 则为 -uroot-p &am…

学习python第7天

Python绘制图形库turtle 1.介绍&#xff1a; turtle库根据一组函数指令的控制&#xff0c;在平面坐标系中移动&#xff0c;从 而它爬行的路径上绘制图形。 2.原理&#xff1a;turtle(海龟&#xff09;由程序控制在画布上游走&#xff0c;走过的轨迹形成绘 制的图形&#xff0c…

子不语IPO下限定价:预计2022年全年净利润下滑,华丙如为实控人

11月10日&#xff0c;子不语集团有限公司&#xff08;HK:02420&#xff0c;下称“子不语”&#xff09;在港交所公布发售结果。公告显示&#xff0c;子不语在香港公开发售及国际配售&#xff08;不含基石部分&#xff09;阶段均获得超额认购&#xff0c;将于2022年11月11日在港…

【前端】Vue+Element UI案例:通用后台管理系统-登陆页面Login

文章目录目标代码0.路由1.结构2.校验规则3.样式总代码Login.vue效果本篇很短&#xff0c;因为只有一个页面。没有功能。 目标 登陆页面&#xff0c;路由为/login有表单验证 代码 0.路由 在router的index.js文件中的routes中添加对象&#xff1a; {path:/login,component:L…

SpringBoot+Mybatis+CRUD项目

一、项目要求 创建一个 SpringBoot 项目&#xff0c;项目名”week11_学号”&#xff1b;使用 Mybatis 框架&#xff0c;也可以时可用 MybatisPlus 框架&#xff1b;访问 myschool 数据库&#xff1b;对 student 表进行操作&#xff0c;向 student 插入自己的一条记录&#xff…

Linux学习-29-用户组信息相关命令

8.17 Linux groupadd命令&#xff1a;添加用户组 添加用户组的命令是 groupadd&#xff0c;命令格式如下: [rootCncLucZK ~]# groupadd [选项] 组名选项&#xff1a; -g GID&#xff1a;指定组 ID&#xff1b;-r&#xff1a;创建系统群组。-o 一般与-g选项同时使用&#xff0…