【算法】二分查找



快乐的流畅:个人主页


个人专栏:《算法神殿》《数据结构世界》《进击的C++》

远方有一堆篝火,在为久候之人燃烧!

文章目录

  • 引言
  • 一、二分查找
  • 二、查找元素的第一个和最后一个位置
  • 三、x的平方根
  • 四、搜索插入位置
  • 五、山脉数组的峰顶索引
  • 六、寻找峰值
  • 七、寻找旋转数组中的最小值
  • 八、寻找旋转数组中的最小值 ||
  • 总结

引言

二分查找,实际上也是左右双指针的变形,本质是利用数组的二段性进行查找。总共有三个模板:朴素二分、左边界二分、右边界二分

一、二分查找


思路:

  1. 这道题就是标准的朴素二分,也是最简单最基础的二分
  2. 循环条件:left <= right
  3. 求中点(两种方法都可以):
    • int mid = left + (right-left)/2;//求左中点
    • int mid = left + (right-left+1)/2;//求右中点
  4. 上述求中点方法,可以防止溢出
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;}
};

二、查找元素的第一个和最后一个位置


思路:

  1. 本题便用到了左边界二分和右边界二分
  2. 循环条件:left < right(注意:判断等于会死循环)
  3. 左边界二分:int mid = left + (right-left)/2;//求左中点
  4. 右边界二分:int mid = left + (right-left+1)/2;//求右中点
  5. 出循环后,还要再判断当前位置的值是否为target
class Solution
{
public:vector<int> searchRange(vector<int>& nums, int target){if(nums.size() == 0) return {-1, -1};int begin = -1, end = -1;int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right-left)/2;if(nums[mid] >= target) right = mid;else left = mid + 1;}if(nums[left] == target) begin = left;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;}if(nums[left] == target) end = left;return {begin, end};}
};

三、x的平方根


思路:

  1. 右边界二分
  2. 注意mid*mid数值太大,int 会溢出,所以改成long long
class Solution
{
public:int mySqrt(int x){int left = 1, right = x;while(left < right){long long mid = left + (right - left + 1) / 2;if(mid * mid <= x) left = mid;else right = mid - 1;}return right;}
};

四、搜索插入位置


思路:

  • 左边界二分
class Solution
{
public:int searchInsert(vector<int>& nums, int target){if(target > nums.back()) return nums.size();int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right-left)/2;if(nums[mid] >= target) right = mid;else left = mid + 1;}return left;}
};

五、山脉数组的峰顶索引


思路:

  • 左边界二分(右边界也可以)
class Solution
{
public:int peakIndexInMountainArray(vector<int>& arr){int left = 0, right = arr.size() - 1;while(left < right){int mid = left + (right-left)/2;if(arr[mid] >= arr[mid+1]) right = mid;else left = mid + 1;}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)/2;if(nums[mid] >= nums[mid+1]) right = mid;else left = mid + 1;}return left;}
};

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


思路:

  1. 每次选取right指向的值,作为比较的基准值
  2. 左边界二分
class Solution
{
public: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;else left = mid + 1;}return nums[left];}
};

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


思路:

  1. 这题是上题的变形,主要改变是存在重复元素
  2. 还是左边界二分,不过在 nums[mid] == nums[right] 时,- -right 即可
class Solution
{
public: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;else if(nums[mid] == nums[right]) --right;else left = mid + 1;}return nums[left];}
};

总结

二分查找,是一种十分高效的查找算法,时间复杂度为O(logN),在数组具有二段性时便可应用。

同时,只要掌握并理解了二分的模板,它便是最简单、最容易的一类题型~


真诚点赞,手有余香

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

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

相关文章

【Leetcode每日一题】 分治 - 排序数组(难度⭐⭐)(60)

1. 题目解析 题目链接&#xff1a;912. 排序数组 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 算法思路&#xff1a; 快速排序作为一种经典的排序算法&#xff0c;其核心思想在于通过“分而治之”的策略&#xff…

eCongnition 根据栅格类别图分类分割结果

目录 1、导入标签文件 2、根据栅格类别计算对象类别 3、导出栅格计算的类别 1、导入标签文件 导入栅格类别文件Label.tif 参考&#xff1a;eCongnition 对图像进行多尺度分割-CSDN博客 2、根据栅格类别计算对象类别 对类别栅格创建 mode[Maximum] 特征&#xff0c;该特征…

SQL Serve---嵌套查询

定义 嵌套查询&#xff1a;主要用于复杂的查询中。在SQL语言中&#xff0c;一个Select From Where语句称为一个查询块&#xff0c;将一个查询块嵌套在另一个查询的Where子句或Having短语中的查询称为嵌套查询。 子查询的类型 使用别名的子查询 使用IN和NOT IN的子查询 使用比较…

基于SSM的列车订票管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的列车订票管理系统3拥有两种角色&#xff1b;管理员、用户 管理员&#xff1a;用户管理、车票管理、购票指南管理、系统管理等 用户&#xff1a;发布帖子、登录注册、购票等 1.…

数据结构速成--串

由于是速成专题&#xff0c;因此内容不会十分全面&#xff0c;只会涵盖考试重点&#xff0c;各学校课程要求不同 &#xff0c;大家可以按照考纲复习&#xff0c;不全面的内容&#xff0c;可以看一下小编主页数据结构初阶的内容&#xff0c;找到对应专题详细学习一下。 目录 …

【Linux冯诺依曼体系结构】

目录 1.冯诺依曼体系结构原理 1.冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 输入单元&#…

最新SpringBoot项目财务管理系统

采用技术 最新SpringBoot项目财务管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统登录页面 管理员功能 管理员功能页面 员工管理页面 部…

SpringBoot多数据源(五)

SpringBoot多数据源-集成多个mybatis框架 1.基本框架2.使用2.1项目结构2.2 依赖导入2.3 application.yml配置2.4 创建读与写的SqlSessionFactoryBean 3.总结 1.基本框架 通过启动多个SqlSessionFactoryBean&#xff0c;每个SqlSessionFactoryBean对应一个datasource和指定位置的…

STM32G431RBT6移植FreeRTOS

引言&#xff1a; 本文专门为参加了蓝桥杯嵌入式赛道的同学准备&#xff0c; 大家可能会有这样一个问题&#xff0c; 比完赛之后&#xff0c; 对于像继续使用STM32G431RBT6学习FreeRTOS的&#xff0c; 发现网上的教程使用的板子基本上都是F1和F4的&#xff0c; 其实呢&#xff…

二叉树的最大深度 - LeetCode 热题 37

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 37 天 二叉树第 2 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最…

JAVA面向对象(下 )(一、继承和方法重写)

一、继承 1.1 什么是继承 生活中继承是指&#xff1a; 继承财产>延续财产 继承/遗传 父母的长相&#xff0c;基因 > 延续上一代的基因 继承技能、专业、职位 >延续 继承中华民族的传统文化 > 延续 青出于蓝而胜于蓝 或 长江后浪推前浪&#xff0c;前浪被拍在…

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流 1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data readNPY(train.npy);%% 提取标签的坐标 first_label squeeze(npy_data(2,1,:,:)); h fspecial("gaussian&quo…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

快速了解开发过程中VO、DTO、BO、 DO、PO、POJO、Entity的概念、区别、作用

​ 目录 ​前言 VO&#xff08;Value Object&#xff0c;值对象&#xff09; DTO&#xff08;Data Transfer Object&#xff0c;数据传输对象&#xff09; BO&#xff08;Business Object&#xff0c;业务对象&#xff09; DO&#xff08;Data Object&#xff0c;数据对象…

OpenCV从入门到精通实战(六)——多目标追踪

基于原生的追踪 使用OpenCV库实现基于视频的对象追踪。通过以下步骤和Python代码&#xff0c;您将能够选择不同的追踪器&#xff0c;并对视频中的对象进行实时追踪。 步骤 1: 导入必要的库 首先&#xff0c;我们需要导入一些必要的Python库&#xff0c;包括argparse、time、…

三级等保安全解决方案——实施方案

实施方案设计 本方案将依照国家有关信息安全建设的一系列法规和政策&#xff0c;为电台建立体系完整、安全功能强健、系统性能优良的网络安全系统。以“统一规划、重点明确、合理建设、逐步强化”为基本指导原则。根据电台网络系统不同信息的重要性调整保护策略&#xff0c;不欠…

SpringBoot项目创建,详细流程

一、前言 Spring Boot是一个开源的Java框架&#xff0c;由Pivotal团队&#xff08;现为VMware旗下&#xff09;开发&#xff0c;通过提供默认配置和一系列启动器&#xff08;starters&#xff09;来简化项目配置&#xff0c;使得开发者能够快速启动和运行Spring应用程序。 ‍ …

K8s 部署 elasticsearch-7.14.0 集群 及 kibana 客户端

一、K8s 部署 elasticsearch-7.14.0 集群 安装规划 组件replicas类型es3StatefulSetkibana1Deployment 使用 k8s 版本为&#xff1a;v1.18.0 。 本次使用 OpenEBS 来作为存储引擎&#xff0c;OpenEBS 是一个开源的、可扩展的存储平台&#xff0c;它提供了一种简单的方式来创…

国内首款千亿参数MoE模型APUS-xDAN-4.0:性能逼近GPT-4,可在4090显卡上运行

前言 随着人工智能技术的快速发展&#xff0c;模型参数的数量已成为衡量其复杂性和处理能力的重要指标。近日&#xff0c;国内科技企业APUS与AI创企新旦智能联合宣布&#xff0c;成功开源了国内首个千亿参数的混合专家模型&#xff08;MoE&#xff09;&#xff0c;APUS-xDAN-4…

锁策略和死锁问题

锁策略 乐观锁 vs 悲观锁重量级锁 vs 轻量级锁自旋锁 vs 挂起等待锁读写锁 vs 互斥锁公平锁 vs 非公平锁可重入锁 vs 不可重入锁死锁死锁产生的必要条件如何简单的解决死锁问题 小结 这里不是描述的某个特定锁,而是描述的锁的特性,描述的是"一类锁". 乐观锁 vs 悲观…