力扣刷题——二分查找总结

我们可以总结出二分查找的通用做法和常见变种。二分查找是一种在有序数组中高效查找元素的算法,时间复杂度为 O (log n)。

二分查找的通用模板

二分查找的核心思想是将搜索范围不断缩小一半,直到找到目标元素或确定其不存在。以下是通用模板:

cpp

int binarySearch(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;  // 找到目标} else if (nums[mid] < target) {left = mid + 1;  // 目标在右半部分} else {right = mid - 1;  // 目标在左半部分}}return -1;  // 未找到目标
}

常见变种及处理技巧

1. 查找插入位置(第一个大于等于目标的位置)
  • 特点:返回第一个大于等于target的索引,若所有元素都小于target,则返回数组长度。
  • 关键:循环结束时,left指向第一个大于等于target的位置。

cpp

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 - 1;}}return left;  // 最终left即为插入位置
}
2. 二维矩阵查找
  • 特点:将二维矩阵展开为一维有序数组。
  • 关键:计算一维索引对应的二维坐标。

cpp

bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size(), n = matrix[0].size();int left = 0, right = m * n - 1;while (left <= right) {int mid = left + (right - left) / 2;int row = mid / n, col = mid % n;  // 转换为二维坐标if (matrix[row][col] == target) {return true;} else if (matrix[row][col] < target) {left = mid + 1;} else {right = mid - 1;}}return false;
}
3. 查找元素的第一个和最后一个位置
  • 特点:需要两次二分查找,分别找到左边界和右边界。
  • 关键
    • 左边界:第一个大于等于target的位置。
    • 右边界:第一个大于target的位置减 1。

cpp

vector<int> searchRange(vector<int>& nums, int target) {auto lower = [&](int t) {int left = 0, right = nums.size() - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < t) {left = mid + 1;} else {right = mid - 1;}}return left;};int first = lower(target);if (first >= nums.size() || nums[first] != target) {return {-1, -1};}int last = lower(target + 1) - 1;  // 右边界return {first, last};
}
4. 旋转排序数组中的查找
  • 特点:数组被旋转后,左右半部分仍有序,但整体无序。
  • 关键:通过比较nums[mid]nums[0]的关系,确定哪半部分有序,再根据有序部分缩小范围。

cpp

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) {return mid;}if (nums[0] <= nums[mid]) {  // 左半部分有序if (target >= nums[0] && target < nums[mid]) {right = mid - 1;  // 目标在左半部分} else {left = mid + 1;  // 目标在右半部分}} else {  // 右半部分有序if (target > nums[mid] && target <= nums.back()) {left = mid + 1;  // 目标在右半部分} else {right = mid - 1;  // 目标在左半部分}}}return -1;
}
5. 寻找旋转排序数组中的最小值
  • 特点:最小值是旋转点,左侧元素都大于右侧元素。
  • 关键:比较nums[mid]与最右侧元素的大小,确定旋转点位置。

cpp

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]) {  // 最小值在左侧right = mid - 1;} else {  // 最小值在右侧left = mid + 1;}}return nums[left];  // 最终left指向最小值
}

二分查找的关键点总结

  1. 循环条件:通常为left <= right,确保不漏掉最后一个元素。
  2. 中间索引计算:使用mid = left + (right - left) / 2防止整数溢出。
  3. 边界调整
    • 若目标在右侧,left = mid + 1
    • 若目标在左侧,right = mid - 1
  4. 变种处理
    • 查找左边界:找到第一个大于等于target的位置。
    • 查找右边界:找到第一个大于target的位置减 1。
    • 旋转数组:通过比较nums[mid]与边界元素,确定有序部分。

掌握这些技巧后,可以灵活应对各种二分查找的变种问题。

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

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

相关文章

开源数字人框架 AWESOME-DIGITAL-HUMAN 技术解析与应用指南

一、项目概述 AWESOME-DIGITAL-HUMAN 是一个基于 Live2D 技术的开源数字人框架&#xff0c;它集成了语音识别&#xff08;ASR&#xff09;、大语言模型&#xff08;LLM&#xff09;、语音合成&#xff08;TTS&#xff09;和 Agent 模块化扩展能力&#xff0c;支持快速部署和自…

互联网大厂Java求职面试:基于RAG的智能问答系统设计与实现-2

互联网大厂Java求职面试&#xff1a;基于RAG的智能问答系统设计与实现-2 面试背景 郑薪苦是一名Java开发者&#xff0c;拥有丰富的项目经验&#xff0c;但在面试中总喜欢用奇葩比喻解释技术问题。今天他面对的是某大厂技术总监张总&#xff0c;面试主题为“基于RAG的智能问答…

(二)Linux下基本指令 2

【知识预告】 16. date 指令 17. cal 指令 18. find 指令 19. which指令 20. whereis 指令 21. alias 指令 22. grep 指令 23. zip/unzip 指令 24. tar 指令 25. bc 指令 26. uname ‒r 指令 27. 重要的⼏个热键 28. 关机 16 date 指令 指定格式显⽰时间&#xff1a;date %Y-…

命令行解释器中shell、bash和zsh的区别

命令行解释器&#xff08;Command Line Interpreter&#xff09;是一个程序&#xff0c;它的主要作用是接收用户输入的命令&#xff0c;并执行相应的操作。它充当了用户与操作系统内核之间的桥梁。 一、什么是 Shell&#xff1f; Shell 是一个通用术语&#xff0c;指的是 命令…

二、transformers基础组件之Tokenizer

在使用神经网络处理自然语言处理任务时&#xff0c;我们首先需要对数据进行预处理&#xff0c;将数据从字符串转换为神经网络可以接受的格式&#xff0c;一般会分为如下几步: - Step1 分词:使用分词器对文本数据进行分词(字、字词);- Step2 构建词典:根据数据集分词的结果,构建…

镜像和容器的管理

一、镜像的管理 获取镜像并生成相关容器 # 拉取镜像 docker pull alpine # 默认是latest&#xff0c;也就是最新版本&#xff0c;也可指定版本&#xff08;在镜像名后边加“:版本号”&#xff09; # 或者 # 从主机中导入镜像到docker中 docker image load -i /test#生成容器 …

设计模式简述(十九)桥梁模式

桥梁模式 描述基本组件使用 描述 桥梁模式是一种相对简单的模式&#xff0c;通常以组合替代继承的方式实现。 从设计原则来讲&#xff0c;可以说是单一职责的一种体现。 将原本在一个类中的功能&#xff0c;按更细的粒度拆分到不同的类中&#xff0c;然后各自独立发展。 基本…

ImportError: DLL load failed: 找不到指定的程序。

查看其他博客说是缺少libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll 然后去下载放到博客说的目录下 没有用 解决不了一点 OpenSSL for Windows 64位 完整安装包 在这里 项目地址: https://gitcode.com/open-source-toolkit/eb627 注意事项 此安装包仅适用于64位Windows系…

电池单元和电极性能

电芯设计中的挑战 对于电池制造商来说&#xff0c;提高电池能量和功率密度至关重要。在高功率密度和长循环寿命之间取得平衡是电池设计中的关键挑战&#xff0c;通常需要仔细优化材料、电极结构和热管理系统。另一个关键挑战是通过优化重量体积比来降低电池单元的总体成本。 工…

数据加密与隐私保护:让你的信息固若金汤

数据加密与隐私保护:让你的信息固若金汤 大家好,我是 Echo_Wish,今天聊聊一个 人人都关心、但很多人没做好 的话题——数据加密与隐私保护的最佳实践。 为什么要重视数据安全? 现在是数字化时代,从个人照片、银行卡信息到企业机密,数据泄露的风险无处不在。你可能觉得自…

【高数上册笔记篇02】:数列与函数极限

【参考资料】 同济大学《高等数学》教材樊顺厚老师B站《高等数学精讲》系列课程 &#xff08;注&#xff1a;本笔记为个人数学复习资料&#xff0c;旨在通过系统化整理替代厚重教材&#xff0c;便于随时查阅与巩固知识要点&#xff09; 仅用于个人数学复习&#xff0c;因为课…

C++(8):类型限定符

目录 1. const&#xff1a;定义常量 2. volatile&#xff1a;易变性修饰 3. restrict&#xff08;C非标准&#xff09; 4. mutable&#xff1a;突破常量性 5. static&#xff1a;静态存储 6. register&#xff08;已弃用&#xff09; 分类修正说明 1. const&#xff1a;…

Nginx yum 安装

一、环境准备 一台装有 CentOS 7.9 的虚拟机 二、安装 安装 yum install -y nginx -y&#xff1a;所有的安装选项都选择 yes。 启动 nginx systemctl enable nginx --now enable&#xff1a;设置 nginx 为开机启动。--now&#xff1a;马上启动 nginx。 查看 nginx 服务状态…

【5分钟学Docker】Docker快速使用

目录 1. 概述 2. 基本操作 2.1. 镜像操作 2.2. 容器操作 2.3. 运行操作 2.4. 镜像保存 2.5. 镜像分享 3. 高级操作 4. 挂载 4.1. 目录挂载 4.2. 卷映射 1. 概述 Docker 镜像有镜像名称和TAG 2. 基本操作 2.1. 镜像操作 查看镜像 docker images docker image ls …

5000字总结 HTML5 中的音频和视频,关羽标签、属性、API 和最佳实践

HTML5 音频与视频开发完全指南&#xff1a;标签、属性、API 与最佳实践 一、引言&#xff1a;HTML5 媒体时代的到来 在 HTML5 之前&#xff0c;网页中的音频和视频播放依赖 Flash、Silverlight 等第三方插件&#xff0c;存在兼容性差、性能瓶颈和安全隐患。HTML5 引入的 <…

【C语言】(9)—指针3

文章目录 一、字符指针的深入理解二、数组指针详解三、二维数组传参的本质四、函数指针及其应用五、函数指针数组与转移表 一、字符指针的深入理解 1.1 字符指针的基本使用 字符指针(char*)是指向字符类型数据的指针&#xff0c;它有两种常见的使用方式&#xff1a; // 方式一…

MDK调试技巧

1、自动生成反汇编 fromelf -c -o "$LL.txt" "#L" 解释&#xff1a; 1、fromelf 是 ARM Compiler 工具链中的一个命令行工具&#xff0c;从fromelf这个名字上我们就能看到它是用来处理elf文件的&#xff0c;elf 全称 Executable and Linking Format &…

嵌入式STM32学习——433M无线遥控灯

1.433M无限模块工作原理&#xff1a; 数据发射模块的工作频率为315M&#xff0c;采用声表谐振器SAW稳频&#xff0c;频率稳定度极高&#xff0c;当环境温度在-25~85度之间变化时&#xff0c;频飘仅为3ppm。 接收到信号&#xff0c;接收模块对应针脚输出高电平&#xff0c;有DO…

JDBC工具类的三个版本

一、JDBC连接数据库的7个步骤 1、加载驱动 2、获取连接 3、编写sql 4、获取执行sql的stmt对象 有两种 stmt&#xff08;存在sql注入问题 字符串拼接&#xff09; pstmt&#xff08;预编译可以防止sql注入&#xff09; 5、执行sql 拿到结果集 6、遍历结果集 7、关闭资源…

3.1/Q1,Charls最新文章解读

文章题目&#xff1a;Predictive model for sarcopenia in chronic kidney disease: a nomogram and machine learning approach using CHARLS data DOI&#xff1a;10.3389/fmed.2025.1546988 中文标题&#xff1a;慢性肾病肌肉减少症的预测模型&#xff1a;使用 CHARLS 数据的…