当前位置: 首页 > article >正文

CC53.【C++ Cont】二分查找的普通模版

目录

1.知识回顾

2.关键点

特点

三个模版

普通的模版(有局限)

以LeetCode上的一道题为例:704. 二分查找

分析

引入二段性:分两段,舍一段,操作另一段(这个是二分查找的本质!)

代码

提交结果

当然也可以使用随机数来分两段

普通模版总结


1.知识回顾

之前在C语言专栏中的文章提到了二分查找,可复习:

E7.【C语言】练习:在一个有序数组中查找具体的某个数字n(二分查找)

本文将提炼出一些关键点

2.关键点

特点

算法细节较多,一 一介绍:

之前讲过二分查找的前提: 数组有序时才能使用二分查找,其实并不是这样!,

当数组满足某特定规律时,也可以使用二分查找(这个后面会介绍)

三个模版

有以下二分查找的固定格式,做题只需要照葫芦画瓢,注意先理解再记忆

普通的模版(有局限)

以LeetCode上的一道题为例:704. 二分查找

https://leetcode.cn/problems/binary-search/description/

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1
示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。
分析

暴力解法直接从左向右或从右向左找,这里不写,讲讲暴力解法的缺陷:每次只能比较一个数,时间复杂度为O(N)

注意到题目条件"一个 n 个元素有序的(升序)整型数组 nums ",那么可以利用数组的单调性对暴力解法优化

以nums = [-1,0,3,5,9,12], target = 9为例说明,现查找到3,发现target>3且数组单增,那么3的左侧是不需要查找的,继续查找3的右侧

引入二段性:分两段,舍一段,操作另一段(这个是二分查找的本质!)

对于上述单增数组有许多分段方式:

1.二分

即近似分成二等分

2.三分

将数组近似分成三等分

然后任意选一个节点来分段,例如:

3.四分

将数组近似分成四等分......

......

当然也可以使用随机数来分段

其中二分的时间复杂度是最低的,时间复杂度为O(logN),当然某些情况下使用随机数来分段时间复杂度也比较低

算法:设数组是单调递增的,对它平分两段:

比较nums[mid]和num[target]的大小,

1.nums[mid]==num[target],结束循环,返回结果

2.nums[mid]<num[target],依据二段性:分两段,舍一段,操作另一段

,舍弃[left,mid]段,去[mid,right]段寻找,那么更新left

left=mid+1;//right不变

nums[mid]>num[target],返回结果,依据二段性:分两段,舍一段,操作另一段

,舍弃[mid,right]段,去[left,mid]段,那么更新right

right=mid-1;//left不变

3.更新mid(有多种方法,上面提过了)

只需要循环上面三步,变化寻找的区间,最终一定可以找到结果

结束循环的两个条件:

1.nums[mid]==num[target],直接返回结果

2.left>right,(注:left==right,分的段是一个"点",只有一个元素,但也需要判断是否等于target,仍然需要循环),没有找到target

那么循环的条件是:left\leqslantright

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

注:mid不要写成(left+right)/2!之前在L42.【LeetCode题解】四数之和(双指针思想) 从汇编角度分析报错原因文章提到过报错的原因,当数组过长时,加法可能导致溢出

防溢出的方法:(left+right)/2改为left+(right-left)/2或left+(right-left+1)/2

提交结果

同理三分法只需要将除数2改成3即可,四分法、五分法同理

mid=left+(right-left+1)/3;
当然也可以使用随机数来分两段
class Solution {
public:int search(vector<int>& nums, int target) {srand((unsigned int)time(nullptr));int left=0;int right=nums.size()-1;int mid;while(left<=right){mid=left+rand()%(right - left + 1);if (nums[mid]==target)return mid;if (nums[mid]>target)right=mid-1;if (nums[mid]<target)left=mid+1;   }return -1;}
};

注: 循环体中,如果最后更新mid将导致除0错误!

这样写是错误的:

class Solution {
public:int search(vector<int>& nums, int target) {srand((unsigned int)time(nullptr));int left=0;int right=nums.size()-1;int mid=left+rand()%(right - left + 1);while(left<=right){if (nums[mid]==target)return mid;if (nums[mid]>target)right=mid-1;if (nums[mid]<target)left=mid+1;mid=left+rand()%(right - left + 1);   }return -1;}
};

排查错误:

VS中进入调试模式

发生错误的地方是: mid = left + rand() % (right - left + 1),则mid=2+rand()%(1-2+1)=2+rand()%0,为除0错误,此时left仍然<=right,策略:先更新mid的值,这样进行if判断时能修改left和right的值,能及时退出循环,防止除0错误

提交结果:

普通模版总结

利用二段性填以下模版空缺的地方:

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

注意1.判断条件 2.mid防溢出方法 3.left和right的更新方式

其他两个模版见下一篇文章

相关文章:

CC53.【C++ Cont】二分查找的普通模版

目录 1.知识回顾 2.关键点 特点 三个模版 普通的模版(有局限) 以LeetCode上的一道题为例:704. 二分查找 分析 引入二段性:分两段,舍一段,操作另一段(这个是二分查找的本质!) 代码 提交结果 当然也可以使用随机数来分两段 普通模版总结 1.知识回顾 之前在C语言专栏…...

泛型加持的策略模式:打造高扩展的通用策略工具类

一、传统策略模式的痛点与突破 1.1 传统策略实现回顾 // 传统支付策略接口 public interface PaymentStrategy {void pay(BigDecimal amount); }// 具体策略实现 public class AlipayStrategy implements PaymentStrategy {public void pay(BigDecimal amount) { /* 支付宝支…...

【优选算法 | 链表】链表操作技巧:常见算法

算法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;双指针滑动窗口二分查找前缀和位运算模拟 链表是一种灵活的数据结构&#xff0c;广泛用于需要频繁插入和删除的场景。掌握链表的常见操作技巧&#xff0c;如插入、删除、翻转和合并等&#xff0c;能帮助开发者更…...

HTTP:十三.HTTP日志

日志记录 日志记录了跟踪使用情况、安全性、计费、错误检验。记录事务的基本信息。通常会记录下来的几个字段示例为: HTTP方法:主要记录事务用了什么方法客户端和服务器的HTTP版本:给出客户端和服务器有关的提示,比如兼容性提示什么的所请求资源的URL:记录Web站点某个资源…...

web 自动化之 selenium 元素四大操作三大切换等待

文章目录 一、元素的四大操作二、三大切换&等待1、切换窗口:当定位的元素不在当前窗口&#xff0c;则需要切换窗口2、切换iframe&#xff1a;当定位的元素在frame/iframe&#xff0c;则需要切换3、切换弹出窗口 一、元素的四大操作 1、输入 2、点击 3、获取文本 4、获取属…...

FEKO许可证的安全与合规性

在电磁仿真领域&#xff0c;FEKO软件因其出类拔萃的性能和广泛的应用场景&#xff0c;赢得了全球用户的广泛赞誉。但在这背后&#xff0c;是什么让FEKO在众多竞争者中脱颖而出&#xff1f;答案是其许可证的安全与合规性。它们不仅为用户提供了坚固的保障&#xff0c;更确保了用…...

w~大模型~合集30

我自己的原文哦~ https://blog.51cto.com/whaosoft/13284996 #VideoMamba 视频理解因大量时空冗余和复杂时空依赖&#xff0c;同时克服两个问题难度巨大&#xff0c;CNN 和 Transformer 及 Uniformer 都难以胜任&#xff0c;Mamba 是个好思路&#xff0c;让我们看看本文是…...

PBR材质-Unity/Blender/UE

目录 前言&#xff1a; 一、Unity&#xff1a; 二、Blender&#xff1a; 三、UE&#xff1a; 四、全家福&#xff1a; 五、后记&#xff1a; 前言&#xff1a; PBR流程作为表达物理效果的经典方式&#xff0c;很值得一学。纹理贴图使用的是上一期的Textures | cgbookcas…...

websocketpp 安装及使用

介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的消息推送机制。 传统的 web 程序都是属于 "一问一答" 的形式&#xff0c;即客户端给服务器发送了一个 HTTP 请求&#xff0c;服务器给客户端返回一个 HTTP 响应。这种情况下服务器是属于被动…...

web:InfiniteScroll 无限滚动

InfiniteScroll 无限滚动 分页加载 <div class"data-box" v-infinite-scroll"loadMore"> <li v-fori in dataList></li> </div>form: {current: 1,size: 10,}loadMore(){console.log(this.dataList.length, this.total ,8888)if…...

LeetCode[101]对称二叉树

思路&#xff1a; 对称二叉树是左右子树对称&#xff0c;而不是左右子树相等&#xff0c;所以假设一个树只有3个节点&#xff0c;那么判断这个数是否是对称二叉树&#xff0c;肯定是先判断左右两个树&#xff0c;然后再看根节点&#xff0c;这样递归顺序我们就确认了&#xff0…...

c/c++爬虫总结

GitHub 开源 C/C 网页爬虫探究&#xff1a;协议、实现与测试 网页爬虫&#xff0c;作为一种自动化获取网络信息的强大工具&#xff0c;在搜索引擎、数据挖掘、市场分析等领域扮演着至关重要的角色。对于希望深入理解网络工作原理和数据提取技术的 C/C 开发者&#xff0c;尤其是…...

js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果

开启流式请求&#xff1a;向后端接口发起普通的 fetch&#xff0c;它会返回一个包含 ReadableStream 的 Response 对象获取流式读取器&#xff1a;调用 response.body.getReader() 获取一个 ReadableStreamDefaultReader 实例循环读取数据块&#xff1a;在 while(true) 循环或 …...

第8章-2 查询执行的基础

上一篇&#xff1a;《第8章-1 查询性能优化-优化数据访问》&#xff0c;接着来了解查询执行的过程&#xff0c;这个对sql执行有个更直观的了解。 查询执行的基础 当希望MySQL能够以更高的性能运行查询时&#xff0c;最好的办法就是弄清楚MySQL是如何优化和执行查询的。一旦理解…...

java面试OOM汇总

在正式 Minor GC 前&#xff0c;JVM 会先检查新生代中对象&#xff0c;是比老年代中剩余空间大还是小。假如 Minor GC之后 Survivor 区放不下剩余对象&#xff0c;这些对象就要进入老年代 老年代剩余空间大于新生代中的对象大小&#xff0c;那就直接 Minor GC&#xff0c; GC 完…...

Java面试全记录:Spring Cloud+Kafka+Redis实战解析

Java面试全记录&#xff1a;Spring CloudKafkaRedis实战解析 人物设定 面试官&#xff1a;来自某互联网大厂资深架构师&#xff0c;着深灰色西装&#xff0c;手持MacBook Pro 候选人&#xff1a;张伟&#xff08;随机生成&#xff09;&#xff0c;28岁&#xff0c;硕士&…...

com.fasterxml.jackson.dataformat.xml.XmlMapper把对象转换xml格式,属性放到标签<>里边

之前从没用过xml和对象相互转换&#xff0c;最近项目接了政府相关的。需要用xml格式数据进行相互转换。有些小问题&#xff0c;困扰了我一下下。 1.有些属性需要放到标签里边&#xff0c;有的需要放到标签子集。 2.xml需要加<?xml version"1.0" encoding"…...

LiveData:Android响应式编程的核心利器

LiveData是一种可观察的数据持有类,用于在Android应用中实现数据的响应式编程。它具有以下特点和作用: 特点 生命周期感知:LiveData能够感知与其关联的组件(如Activity、Fragment)的生命周期状态。只有当组件处于活跃状态(如Activity处于RESUMED状态)时,LiveData才会将…...

Browserless 快速上手

要将你提供的 HTML 模板和数据结构转换为可以用于 Browserless /pdf 接口的 JSON 请求体&#xff08;且能正确渲染为 PDF&#xff09;&#xff0c;需要满足以下几点&#xff1a; ✅ 最终目标格式&#xff08;这是能用的格式&#xff09;&#xff1a; json 复制编辑 { "h…...

安装Hadoop并运行WordCount程序

一、安装 Java Hadoop 依赖 Java&#xff0c;首先需要安装 Java 开发工具包&#xff08;JDK&#xff09;。以 Ubuntu 为例&#xff1a; bash sudo apt update sudo apt install openjdk-8-jdk安装后&#xff0c;设置环境变量&#xff1a; bash echo export JAVA_HOME/usr/li…...

react-diff-viewer 如何实现语法高亮

前言 react-diff-viewer 是一个很好的 diff 展示库&#xff0c;但是也有一些坑点和不完善的地方&#xff0c;本文旨在描述如何在这个库中实现自定义语法高亮。 Syntax highlighting is a bit tricky when combined with diff. Here, React Diff Viewer provides a simple rend…...

自定义prometheus exporter实现监控阿里云RDS

# 自定义 Prometheus Exporter 实现多 RDS 数据采集## 背景1. Prometheus 官网提供的 MySQL Exporter 对于 MySQL 实例只能一个进程监控一个实例&#xff0c;数据库实例很多的情况下&#xff0c;不方便管理。 2. 内部有定制化监控需求&#xff0c;RDS 默认无法实现&#xff0c;…...

【计算机网络】--tcp三次握手

文章目录 示意图&#xff1a;抓包结果&#xff1a;第一次握手&#xff08;Client → Server&#xff09;第二次握手&#xff08;Server → Client&#xff09;第三次握手&#xff08;Client → Server&#xff09;为什么是三次握手 不是两次或者四次 示意图&#xff1a; 抓包结…...

List<T>中每次取固定长度的数据

工具类方法 package org.common.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List;/*** 批处理取值组件* param <T>*/ public class BatchIterator<T> implements Iterator<List<T>> {private final List<T&g…...

UI-TARS: 基于视觉语言模型的多模式代理

GitHub&#xff1a;https://github.com/bytedance/UI-TARS 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI 基于视觉语言模型&#xff08;Vision-Language Model&#xff09;的 GUI 代理应用&#xff0c;允许用户通过自然语言控制电脑操…...

02_线性模型(回归线性模型)

描述 线性模型是在实践中广泛使用的一类模型&#xff0c;线性模型利用输入特征的线性函数&#xff08;linear function&#xff09;进行预测。 用于回归的线性模型 对于回归问题&#xff0c;线性模型预测的一般公式如下&#xff1a; $ \widehat y w[0]*x[0]w[1]*x[1]…w[p…...

Spark SQL 运行架构详解(专业解释+番茄炒蛋例子解读)

1. 整体架构概览 Spark SQL的运行过程可以想象成一个"SQL查询的加工流水线"&#xff0c;从原始SQL语句开始&#xff0c;经过多个阶段的处理和优化&#xff0c;最终变成分布式计算任务执行。主要流程如下&#xff1a; SQL Query → 解析 → 逻辑计划 → 优化 → 物理…...

【计算机网络】网络IP层

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;传输层协议TCP 下篇文章&#xff1a;数据链路层 文章摘要&#xff1…...

一天学会Maven

一、Maven简介和快速入门 1.1 Maven介绍 Maven 是一款为 Java 项目构建管理、依赖管理的工具&#xff08;软件&#xff09;&#xff0c;使用 Maven 可以自动化构建、测试、打包和发布项目&#xff0c;大大提高了开发效率和质量。 总结&#xff1a;Maven就是一个软件&#xf…...

CentOS部署Collabora Online

1.安装Docker CentOS7安装Docker(超详细)-CSDN博客 2.拉取镜像 docker pull collabora/code:latest 3. 启动容器&#xff08;直接暴露HTTP端口&#xff09; docker run -d --name collabora -p 9980:9980 -e "usernameadmin" -e "password123456" -e …...