【刷题】 二分查找入门

在这里插入图片描述

送给大家一句话:

总有一天,你会站在最亮的地方,活成自己曾经渴望的模样—— 苑子文 & 苑子豪《我们都一样 年轻又彷徨》

二分查找入门

  • 1 前言
  • 2 Leetcode 704. 二分查找
    • 2.1 题目描述
    • 2.2 算法思路
  • 3 Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    • 3.1 题目描述
    • 3.2 算法思路
      • 算法优化
        • 循环条件
        • 求中点的操作
  • Leetcode 35. 搜索插入位置
    • 题目描述
    • 算法思路
  • Leetcode 69. x 的平方根
    • 题目描述
    • 算法思路
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

1 前言

二分算法是一种非常强大的算法!!!
想象你在一本厚厚的字典里查找一个词。这本字典的词都是按字母顺序排列的。如果你像小学生学习拼音那样一页一页翻,肯定效率很低,因为这样你要查很久。二分查找算法就像是一个聪明的查词策略,它可以帮你快速定位到那个词。

使用二分查找时:

  1. 你会先打开字典的中间,看这一页的词是不是你要找的,如果不是,你再看这个词是在你要找的词的前面还是后面。
  2. 如果在前面,那你就把后半部分的查找范围排除掉,只在前半部分继续查找;
  3. 如果在后面,就排除掉前半部分。然后,你再在剩下的那一半中找到中间,重复之前的步骤。

通过这样一分为二,一步步缩小范围的方式,直到找到那个词,这个过程就是二分查找。
这个方法之所以有效,是因为每次查找你都排除了一半的可能性,大大提高了查找效率。就像在一个有序的环境中找东西,知道了规则,就能迅速定位,节省了大量的时间。

二分查找主要有三种模版:朴素算法,左端点算法,右端点算法。下面我们一起来通过题目认识二分查找算法吧!

2 Leetcode 704. 二分查找

上链接!!!704. 二分查找

2.1 题目描述

在这里插入图片描述
这是一一道非常经典的二分查找题目,我们来看样例:

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

很好理解二分查找的寻找过程,下面我们来看代码。

2.2 算法思路

  1. 首先先定义左右端点
  2. 判断中间是不是满足条件
  3. 如果大于那么右端点移到中间的左边
  4. 反之左端点移到中间的右边
  5. 直到找到为止

这道题无需考虑很多,使用朴素二分查找即可:

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

下面的题目我们来详细讲解左端点二分和右端点二分!

3 Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置

上链接!!!34. 在排序数组中查找元素的第一个和最后一个位置

3.1 题目描述

在这里插入图片描述
这道题分别要寻找目标值的开始索引和终止索引。来看样例:

  • 输入:nums = [5,7,7,8,8,10], target = 8
  • 输出:[3,4]

3.2 算法思路

先来看暴力算法,遍历所有的元素,记录起始和终止位置既可以,但是这样就浪费了数组有序的重要特性!!!
那使用朴素算法呢? 可以是可以,但是时间复杂度会很大!遇到数组全部是目标值的时候,第一次就能命中对应目标值,但要寻找到起始和中止就要遍历所有的元素,这样就和暴力算法没有区别了!所以不推荐朴素算法

算法优化

我们来看朴素算法的优化版本:左端点二分和右端点二分
这道题实际上可以分成两个问题:

  1. 查找左端点
  2. 查找右端点

先看左端点:我们可以把数组分为两部分:小于target 的部分 ,大于等于target 的部分。然后我们分类讨论(x 为 中间值):

  1. x < t 那么 left = mid + 1 更新新区间
  2. x >= t 那么 right = mid (不能越过mid,因为mid 有可能是答案所在位置) 更新区间

在来看难点 : 循环条件 和 求中点的操作

循环条件

到底是left < right 还是 left <= right ???我们来分类讨论一下:

  1. 如果有结果,那么left 是一直想要跳出这个区域,如果相遇那么此位置就是结果(无需判断),如果判断就会陷入死循环
  2. 如果全大于 t , 那么只能right 移动,最终相遇时,如果是(left <= right )就会死循环,我们只需判断该值是否等于 t
  3. 如果全小于 t , 那么只能left 移动,最终相遇时 ,如果是(left <= right )就会死循环,我们只需判断该值是否等于 t
求中点的操作

求中点也是有两种:

  1. left + (right - left ) / 2
  2. left + (right - left + 1) / 2

如果仅剩两个元素时,使用第二种时,如x >= t 那么right 就不动了!!!陷入了死循环!!!
所以要使用第一种!!!

右端点也是同样的分析思路,不同的是:

  1. x <= t 那么 left = mid 更新新区间
  2. x > t 那么 right = mid - 1 (不能越过mid,因为mid 有可能是答案所在位置) 更新区间
  3. 求中点操作要用第二种办法
    这样就完成了:
class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.size() == 0) return {-1,-1};int begin = 0 , end = 0;int left = 0, right = nums.size() - 1;//先找左点//左边都小于 t 右边大于等于 t //左边不合法 右边合法while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target) left = mid + 1;else right = mid;}if(nums[left] == target) begin = left;else return {-1,-1};//进行右边操作//左边都小于等于 t 右边大于 t //左边合法 右边不合法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;}end = right;return {begin,end};}
};

提交就过啦!!!

Leetcode 35. 搜索插入位置

家人们!!!上链接!!!35. 搜索插入位置

题目描述

在这里插入图片描述
这道题很好理解,找到对应位置插入即可!!!

算法思路

当然暴力算法很好想,但是我们不用。
通过上一道题的思路,我们很容易想到使用左端点二分的方法,因为插入是在该数的前面插入。

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0 , right = nums.size() - 1;int ans = 0;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target) left = mid + 1;else right = mid;}//避免比最大的数大,此时是在后面插入if(left == nums.size() - 1 && target > nums[left]) ans = left + 1;else ans = left;return  ans ; }
};

提交!过啦!!!!

Leetcode 69. x 的平方根

上链接!!!69. x 的平方根

题目描述

在这里插入图片描述

这道题很好理解奥,我们要实现找到算术平方根。即平方小于x 的最大的数。

算法思路

暴力算法很好想,一个一个试就可以,但是使用二分算法更加快速。
我们可以把数字抽象为左右端,left 为 0 right = x 。然后开始二分(判断条件是mid 的平方与x的比较)。因为是找最大的所以使用右端点二分

class Solution {
public:int mySqrt(int x) {//初始化 右值设置为 x 的一半进一步可以避免平方超范围int left = 0 , right = x / 2 + 1;while(left < right){   // 使用long long =防止超出int范围long long  mid = left + (right - left + 1) / 2;if(mid * mid <= x) left = mid ;else right = mid - 1 ;}return left;}
};

提交:过啦!!!!

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

学习笔记——C语言基本概念指针(下)——(8)

1.指针和数组 数组指针 -- 指向数组的指针。 指针数组 -- 数组的元素都是指针。 换句话理解就是&#xff1a;数组指针就是个指针&#xff0c;指针数组就是个数组。 1.1数组指针 数组指针&#xff1a;指向数组的指针&#xff1b; 先回顾一下数组的特点&#xff1a; 1.相…

【C语言】联合体、枚举: 联合体与结构体区别,枚举的优点

目录 1、联合体 1.1、什么是联合体 1.2、联合体的声明 1.3、联合体的特点 1.4、联合体与结构体区别 1.5、联合体的大小 2、枚举 2.1、枚举类型的声明 2.2、枚举类型的优点 3、三种自定义类型&#xff1a;结构体、联合体、枚举 正文 1、联合体 1.1、什么是联合体 联…

如何使用route-detect在Web应用程序路由中扫描身份认证和授权漏洞

关于route-detect route-detect是一款功能强大的Web应用程序路由安全扫描工具&#xff0c;该工具可以帮助广大研究人员在Web应用程序路由中轻松识别和检测身份认证漏洞和授权漏洞。 Web应用程序HTTP路由中的身份认证&#xff08;authn&#xff09;和授权&#xff08;authz&…

题目:小明的背包5(蓝桥OJ 1178)

问题描述&#xff1a; 解题思路&#xff1a; 分组背包模板题&#xff0c;与优化01背包的不同之处在于第一维不可省略&#xff0c;要写s循环。注意要初始化 #include <bits/stdc.h> using namespace std; const int N 1e3 9; int dp[N][N]; // 分组背包模板&#xff0c;…

代码随想录阅读笔记-二叉树【平衡二叉树】

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 返回 true 。 示例 2: 给定二叉树 [1,2,…

ZKFair 创新之旅,新阶段如何塑造财富前景

在当前区块链技术的发展中&#xff0c;Layer 2&#xff08;L2&#xff09;解决方案已成为提高区块链扩容性、降低交易成本和提升交易速度的关键技术&#xff0c;但它仍面临一些关键问题和挑战&#xff0c;例如用户体验的改进、跨链互操作性、安全性以及去中心化程度。在这些背景…

Unity中UI系统1——GUI

介绍 工作原理和主要作用 基本控件 a.文本和按钮控件 练习&#xff1a; b.多选框和单选框 练习&#xff1a; 用的是第三种方法 c.输入框和拖动框 练习&#xff1a; 练习二&#xff1a; e.图片绘制和框 练习&#xff1a; 复合控件 a.工具栏和选择网格 练习&#xff1a; b.滚动视…

纷享销客如何向生态型CRM进化 创始人罗旭给出了答案

自己挣1块钱时&#xff0c;渠道合作伙伴能够挣1块甚至更多。这是纷享销客与生态共建之道。 2024年纷享销客北方战区渠道生态伙伴发展共建会于日前在北京举行。在这场主题为“聚力纷享共赢巅峰”的大会上&#xff0c;各方探讨了企业高质量增长之源与SaaS行业渠道发展之路&#…

云渲染实用工具:3ds max怎么改低版本?

3ds Max是建模领域广泛采用的专业软件&#xff0c;它通过定期更新来不断增强功能和提升性能。但这些频繁的更新有时会导致一些插件暂时无法与新版本完全兼容。为了解决这个问题&#xff0c;设计师们可以采用一个简单有效的方法&#xff0c;那就是将较新版本的3ds Max文件进行版…

基于Unity+Vue3通信交互的WebGL项目发布实践

基于UnityVue3通信交互的WebGL项目发布实践 实践路线 基于UnityVue3通信交互的WebGL项目发布实践问题背景准备工作解决方案项目实践小目标搭建Unity测试项目 创建Vue3测试项目运行项目验证unity和vue通信功能总结与展望 问题背景 我们最近需要把unity开发的pc项目迁移到web端&…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.9-3.11

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第三周&#xff1a;浅层神经网络(Shallow neural networks)3.9 神 经 网 络 的 梯 度 下 降 &#xff08; Gradient descent for neural networks&#xff09;3.10&#xff08;选修&#xff0…

C#让标题栏闪烁着动起来的方法

目录 1.API函数FlashWindow &#xff08;1&#xff09;添加命名空间 &#xff08;2&#xff09;声明DllImport方法 &#xff08;3&#xff09;FlashWindow函数 2.P/Invoke 3.再来一个示例 在Windows系统中&#xff0c;当程序在后台运行时&#xff0c;如果某个窗体的提示信…

环境配置——已解决ModuleNotFoundError: No module named ‘cv2’(python)

一、报错代码 在网上搜到不少用Python处理图形的代码&#xff0c;于是复制别人的代码直接运行却报错&#xff0c;得到的结果却是&#xff1a;已解决ModuleNotFoundError: No module named ‘cv2’。&#xff08;当时心里瞬间凉了一大截&#xff0c;最后顺利解决了&#xff0c;顺…

软考 系统架构设计师系列知识点之云原生架构设计理论与实践(8)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之云原生架构设计理论与实践&#xff08;7&#xff09; 所属章节&#xff1a; 第14章. 云原生架构设计理论与实践 第2节 云原生架构内涵 14.2 云原生架构内涵 关于云原生的定义有众多版本&#xff0c;对于云原生架构的…

脑部肿瘤检测YOLOV8

脑部肿瘤检测&#xff0c;采用YOLOV8训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV调用&#xff0c;支持C/PYTHON/ANDORID开发脑部肿瘤检测YOLOV8

如何在Plesk面板备份网站

本周有一个客户&#xff0c;购买Hostease的Windows虚拟主机&#xff0c;咨询我们的在线客服&#xff0c;询问Windows虚拟主机Plesk面板是否提供备份功能。我们为用户提供教程&#xff0c;用户很快完成了数据备份。在此&#xff0c;我们分享这个操作教程&#xff0c;希望可以对您…

实践笔记-harbor-01搭建(版本:2.9.0)

harbor搭建 1.下载安装包&#xff08;版本&#xff1a;2.9.0&#xff09;2.修改配置文件3.安装4.访问harbor5.可能用得上的命令: 环境&#xff1a;centos7 1.下载安装包&#xff08;版本&#xff1a;2.9.0&#xff09; 网盘资源&#xff1a;https://pan.baidu.com/s/1fcoJIa4x…

多微信聚合聊天神器,让你的社交更高效!

对于那些拥有多个微信号的用户来说&#xff0c;频繁地在不同微信号和设备之间切换既麻烦又容易搞混。这时候&#xff0c;一款多微信聚合聊天神器——微信管理系统应运而生&#xff0c;为我们带来了极大的便利与高效。 下面一起来看看它都有哪些功能吧&#xff01; 1、多微信同…

mybatis plus 的方法有些带填充和逻辑删除,有些又不带

有没有人知道这是怎么个规律。逻辑删除看了下都会自动带上&#xff0c;但是主要是删除和修改方法&#xff0c;有些会按照设置的handler自动填充&#xff0c;有些又不会。有大佬知道吗。

C++ | Leetcode C++题解之第2题两数相加

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {map<int,int> a;//提供一对一的hashvector<int> b(2,-1);//用来承载结果&#xff0c;初始化一个大小为2&#xff0c;值为-1的容…