二分查找 | 二分模板 | 二分题目解析

news2024/9/20 7:57:58
1.二分查找

二分查找的一个前提就是要保证数组是有序的(不准确)!利用二段性!
1.朴素二分模板
朴素二分法的查找中间的值和目标值比较(不能找范围)

while(left <= right)	// 注意是要: <=
{
    int mid = left + (right -left) / 2;	// 避免溢出

    if(条件){
        left = mid + 1;
    }
    else if(条件){
        right = mid -1;
    }
    else{
        return 结果;
    }
}

练习题目:
leetcode704. 二分查找
leetcode33 搜索旋转排序数组
在这里插入图片描述
1、nums[mid] >= nums[left] (以左端点为参考点)说明mid 落在的AB 端 否则落在了CD段
2、当mid落在AB段中,当 target >= nums[left] (以左端点为参考点)&& target < nums[mid] 说明了right = mid -1。否则就是落在了[mid + 1,B]段,移动left = mid + 1;
3、当mid落在了CD段中,当 target <= nums[right](以右端点为参考点) && target > nums[mid] 说明移动left = mid -1。否则right = mid - 1

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;
}

leetcode162 寻找峰值
峰值大于相邻的左和右,mid可以是落在任何位置。这里用到了查找右边界的二分模板
1、当nums[mid] > nums[mid -1] 说明是在递增left 往右移动。left = mid (这里只判断了mid 的左边,mid可能就是峰值)
2、else (即:nums[mid] < nums[mid - 1] ) 说明在递减区域如BC。right = mid - 1。
在这里插入图片描述
参考代码:

int findPeakElement(vector<int>& nums) 
{
	if(nums.size() == 1) return 0;
	if(nums.size() < 3) return nums[1] > nums[0] ? 1 : 0;
	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 left;
}

leetcode35 搜索插入位置
找到数组中的元素,如过找不到,返回target插入的下标索引。
在这里插入图片描述

如上图数组的左边部分的元素是 <target,右边>= target
1、nums[mid] < target 说明 left = mid + 1
2、nums[mid] >= target 说明 right = mid。有可能mid就是要找的元素
3、当循环结束后(left == right)说明数组中的值没有对应的target。当nums[left] < target。说明target要插入在left后面返回 left + 1 否则返回 left。
参考代码:

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) return mid;
        if(nums[mid] < target)
        {
            left = mid + 1;
        }
        else
        {
            right = mid;
        }
    }
    return nums[left] < target ? left +1 : left;
}

leetcode34、在排序数组中查找元素的第一个和最后一个位置
找到最左边的(第一个位置):
在这里插入图片描述

1、当nums[mid] < target则left = mid + 1
2、当nums[mid] >= target 则right = mid (mid可能就是最左边的target)

找到最右边的(最后一个位置):
在这里插入图片描述
1、当nums[mid] > target 则right = mid - 1
2、当nums[mid] <= target 则 left = mid

参考代码:

vector<int> searchRange(vector<int>& nums, int target) 
{
    if(nums.size() == 0) return {-1,-1};
    vector<int> ret;
    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;
        }
    }
    nums[left] == target ? ret.push_back(left) : ret.push_back(-1);

    left = 0;   // 可以的不用重置
    right = nums.size() -1;

    while(left < right)
    {
        int mid = left + (right - left + 1) / 2;

        if(nums[mid] > target)
        {
            right = mid - 1;
        }
        else
        {
            left = mid;
        }
    }
    nums[right] == target ? ret.push_back(left): ret.push_back(-1);
    return ret;
}

leetcode153. 寻找旋转排序数组中的最小值
在这里插入图片描述
1、求最小值,一定是在CD段的,准确说是端点C!但是mid可能会AB段,当落到AB就要移动left,什么条件满足移动呢(参考点是什么)
2、当 nums[mid] > nums[right] 时 left = mid - 1
3、当 nums[mid] <= nums[right] 时 right = mid

int findMin(vector<int>& nums) 
{
    int left = 0,right = nums.size() -1;

    while(left < right)
    {
        int mid = left + (right - left) / 2;

        if(nums[mid] > nums[right])
        {
            left = mid + 1;
        }
        else
        {
            right = mid;
        }
    }
    return nums[left];
}

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

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

相关文章

华为云征文|基于Flexus云服务器X实例的应用场景-私有化部署自己的笔记平台

&#x1f534;大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 先看这里 写在前面效果图华为云Flexus X实例云服务器Blossom 私有化笔记平台简介准备工作创建yaml文件执行yaml文件使用blossom 写在前面 我发现了个事儿&#xff0c;好多技术…

百望云携手春秋航空 迈入航空出行数电票新时代

在数字经济的大潮中&#xff0c;每一个行业的转型与升级都显得尤为关键&#xff0c;而航空业作为连接世界的桥梁&#xff0c;其数字化转型的步伐更是备受瞩目。随着百望云与春秋航空携手迈入航空出行数电票新时代&#xff0c;我们不仅见证了传统纸质票据向数字化转型的必然趋势…

Elastic Stack--ELFK实例与Dashboard界面

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

逆向工程核心原理 Chapter22 | 恶意键盘记录器

教程这一章没给具体的实现&#xff0c;这里在Chapter21学习的基础上&#xff0c;试着实现一个键盘记录器。 键盘记录器实现 这里有个技术问题&#xff1a;记录下的敲击键&#xff08;在KeyHook.dll中捕获的&#xff09;&#xff08;可以用wParam&#xff09;怎么打印出来&…

二叉树和堆知识点

1 特殊二叉树 1. 满二叉树&#xff1a;一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是满二叉树。也就是 说&#xff0c;如果一个二叉树的层数为K&#xff0c;且结点总数是 &#xff0c;则它就是满二叉树。 2. 完全二叉树&#xff1a;完全…

前端打包部署,Nginx服务器启动

前端vue打包部署 前端vue打包部署&#xff0c;执行NPM脚本下的build vue-cli-service... 生成dist文件夹 Nginx服务器 将刚刚的静态资源部署到Nginx

小白学装修(准备阶段)

装修还是 实事求是 脚踏实地 多用心 多学习 视频&#xff1a; 你离摆脱装修小白身份&#xff0c;只差这一个视频&#xff01;_哔哩哔哩_bilibili 本篇文章所涉及到的文件&#xff08;记得给诡计从不拖更一件三联&#xff09; 给诡计投币换的装修预算表资源-CSDN文库 住户…

【Python报错已解决】“ValueError: If using all scalar values, you must pass an index“

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述1.1 报错示例&#xff1a;以下是一个可能引发上述错误的代码示例。1.2 报错分析&#x…

Docker 镜像构建

1、Docker 镜像结构 Docker镜像的结构是分层的&#xff0c;这种结构是Docker镜像轻量化和高效性的关键。每个Docker镜像都由一系列的“镜像层”&#xff08;image layers&#xff09;组成&#xff0c;这些层通过UnionFS&#xff08;联合文件系统&#xff09;技术叠加在一起&am…

磐石云语音识别引擎

磐石云发布了V1.2.2版本语音识别引擎。 经过严格客观的测试识别效果和阿里云、讯飞、火山进行了对比几乎无差。&#xff08;欢迎对比测试&#xff09; 上图是CPU下的流式识别效果 RTF0.1~0.14,也就是一并发一个小时大约处理7~10小时&#xff0c;这取决于硬件的配置&#xff0…

基于SpringBoot的教务与课程管理系统

&#x1f4a5;&#x1f4a5;源码和论文下载&#x1f4a5;&#x1f4a5;&#xff1a;基于SpringBoot的教务与课程管理系统源码论文报告数据库.rar 1. 系统介绍 随着计算机科学技术的迅猛进步及高等教育体系改革的持续深化&#xff0c;传统的教育管理方式、工具及其操作效率已经难…

APP测试(十一)

APP测试要点提取与分析 一、功能测试 APP是什么项目&#xff1f;核心业务功能梳理清楚 — 流程图分析APP客户端的单个功能模块 — 细化分析 需要使用等价类&#xff0c;边界值&#xff0c;考虑正常和异常情况&#xff08;长度&#xff0c;数据类型&#xff0c;必填&#xff0…

JavaFX基本控件-Label

JavaFX基本控件-Label 常用属性textpaddingalignmenttextAlignmentwidthheighttooltipborderwrapTextellipsisStringunderline 实现方式Java实现fxml实现 常用属性 text 设置文本内容 label.setText("这是一个测试数据");padding 内边距 label.setPadding(new Inset…

Python计算机视觉四章-照相机模型与增强现实

目录 4.1针孔照相机模型 4.1.1照相机矩阵 4.1.2 三维点的投影 4.1.3 照相机矩阵的分解 4.1.4 计算照相机中心 4.2 照相机标定 4.2.1 一个简单的标定方法 4.3 以平面和标记物进行姿态估计 4.4 增强现实 4.4.1 PyGame和PyOpenGL 4.4.2 从照相机矩阵到OpenGL格式 4…

部署Rancher2.9管理K8S1.26集群

文章目录 一、实验须知1、Rancher简介2、当前实验环境 二、部署Rancher1、服务器初始化操作2、部署Rancher3、登入Rancher平台 三、Rancher对接K8S集群四、通过Rancher仪表盘部署Nginx服务1、创建命名空间2、创建Deployment3、创建Service 一、实验须知 1、Rancher简介 中文官…

碎碎恋之懒加载和预加载

目录 0 前言1 fragment复习1.1 静态创建1.2 动态创建1.3 两者生命周期1.4 fragment之间的通信 0 前言 懒加载&#xff0c;延迟加载&#xff1b;如kotlin中初始化&#xff1b;减小资源消耗&#xff0c;可以避免同一时间需要加载的内容过多。 预加载&#xff0c;提前加载&#x…

经典大语言模型解读(2):生成式预训练的先锋GPT-1

论文地址&#xff1a;Improving Language Understanding by Generative Pre-Training 概述 现实世界中包含了大量的文本语料数据&#xff0c;然而&#xff0c;绝大多数语料都是无标签的。 为了充分利用这些无标签语料库&#xff0c;GPT1.0提出直接利用这些未标记的语料来进行…

【BLE】三.GATT/ATT规范

基本概念回顾 CS交互流程 SPP&#xff08;蓝牙透传&#xff09;的示例初始化&#xff1a; SPP示例运行过程&#xff1a; GATTS&GAP回调&#xff1a; 黄色&#xff1a;事件回调 绿色&#xff1a;事件 蓝色&#xff1a;执行 GATTC&GAP回调&#xff1a; 服务特征…

安全入门day.04

一、密码存储加密知识点 1、MD5 MD5加密是一种广泛使用的密码杂凑函数&#xff0c;它可以将任意长度的信息通过一系列复杂的数学和位操作转化为一个128位&#xff08;16字节&#xff09;的散列值&#xff08;hash value&#xff09;&#xff0c;这个散列值通常被表示为一个32位…

【Qt】工具栏

工具栏 工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。 在Qt中使用QToolBar表示工具栏对象&#xff0c;一个窗口可以有多个工具栏&#xff0c;也可以没有&#xff0c;工具栏也是可以进行手动移动位置。 例子&#xff1a;创建工具栏 &#xff08;1&#xff09;创…