【刷题】 二分查找入门

在这里插入图片描述

送给大家一句话:

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

二分查找入门

  • 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.rhkb.cn/news/293880.html

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

相关文章

求组合背包II(acwing)

题目描述&#xff1a; 给定n组循问&#xff0c;每组询问给定两个整数a&#xff0c;b&#xff0c;请你输出Ca^b mod (1e9 7)的值&#xff0c;。 输入格式&#xff1a; 第一行包含整数n。 接下来2行&#xff0c;每行包含一组a和b。 输出格式&#xff1a; …

Leetcode 4.1

LeetCode 热题 100 贪心算法1.买卖股票的最佳时机2.跳跃游戏3.跳跃游戏 II4.划分字母区间 区间合并1.合并区间 贪心算法 1.买卖股票的最佳时机 买卖股票的最佳时机 买的那天一定是卖的那天之前的最小值。 每到一天&#xff0c;维护那天之前的最小值即可。 在题目中&#xff0…

面试题:MySQL 优化篇

定位慢查询 &#x1f496; 开源工具 调试工具&#xff1a;Arthas&#xff08;阿尔萨斯&#xff09;运维工具&#xff1a;Prometheus&#xff08;普罗米修斯&#xff09;、Skywalking &#x1f496; MySQL 慢查询日志 # 开启 MySQL 慢查询日志开关 slow_query_log1 # 设置慢…

微信小程序wx.navigateTo无法跳转到Component组件问题解决。(共享元素动画必备)

关于Component构造器官方是有文档说明的&#xff0c;然后官方文档内部也给出了组件是可以通过像pages一样跳转的。但是官方文档缺少了必要的说明&#xff0c;会引起wx.navigateTo无法跳转到组件问题&#xff01; 扫码查看小程序&#xff0c;可以体验效果&#xff1a; 以下是官方…

ElementUI表格table组件实现单选及禁用默认选中效果

在使用ElementUI&#xff0c;需要ElementUI表格table组件实现单选及禁用默认选中效果, 先看下效果图&#xff1a; 代码如下&#xff1a; <template><el-tableref"multipleTable":data"tableData"tooltip-effect"dark"style"widt…

C语言之位段

1.位段的声明 位段的声明和结构是类似的&#xff0c;有两个不同&#xff1a; 1.位段的成员必须是 int、unsigned int 或signed int 。 2.位段的成员名后边有一个冒号和一个数字。 比如&#xff1a; struct A {int _a:2;int _b:5;int _c:10;int _d:30; }; A 就是一个位段类型…

vue3 渲染一个后端返回的图片字段渲染、table表格内放置图片

一、后端直接返回图片url 当图片字段接口直接返回的是图片url&#xff0c;可以直接放到img标签上 <img v-if"thumbLoader" class"r-image-loader-thumb" :src"resUrl" /> 二、当图片字段接口直接返回的是图片Id 那么就需要去拼一下图片…

商品服务 - 三级分类

1.递归查询树形结构 Overridepublic List<CategoryEntity> listWithTree() {//1.查出所有分类List<CategoryEntity> all this.list();//2.组装成父子的属性结构List<CategoryEntity> level1Menus all.stream().filter(c -> c.getParentCid().equals(0L)…

LeetCode-560. 和为 K 的子数组【数组 哈希表 前缀和】

LeetCode-560. 和为 K 的子数组【数组 哈希表 前缀和】 题目描述&#xff1a;解题思路一&#xff1a;一边算前缀和一边统计。这里用哈希表统计前缀和出现的次数&#xff0c;那么和为k的子数组的个数就是当前前缀和-k的个数&#xff0c;即preSums[presum - k]。画个图表述就是&a…

FPGA之状态机学习

作为一名逻辑工程师&#xff0c;掌握和应用状态机设计是必不可少的。能够灵活的应用状态机是对逻辑工程师最基本的要求&#xff0c;状态机设计的好坏能够直接影响到设计系统的稳定性&#xff0c;所以学会状态机是非常的重要。 1.状态机的概念 状态机通过不同的状态迁移来完成特…

Java封装最佳实践:打造高内聚、低耦合的优雅代码~

​ 个人主页&#xff1a;秋风起&#xff0c;再归来~ 文章专栏&#xff1a;javaSE的修炼之路 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克心守己&#xff0c;律己则安&#xff01; 1、封装 1.1 封装的概念 面向对象程序三大…

从0到1利用express搭建后端服务

目录 1 架构的选择2 环境搭建3 安装express4 创建启动文件5 express的核心功能6 加入日志记录功能7 日志记录的好处本节代码总结 不知不觉学习低代码已经进入第四个年头了&#xff0c;既然低代码很好&#xff0c;为什么突然又自己架构起后端了呢&#xff1f;我有一句话叫低代码…

【数据结构】优先级队列——堆

&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;个人主页&#x1f388;&#x1f388;&#x1f388;&#x1f388;&#x1f388; &#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;&#x1f9e7;数据结构专栏&#x1f388;&#x1f388;&#x1f388;&…

数码管时钟--LABVIEW编程

一、程序的前面板 1.获取系统时钟&#xff0c;年月日&#xff0c;时分秒&#xff0c;用14个数码管显示。 2.闹钟设定小时和分钟。 二、程序的后面板 三、程序运行图 四、程序源码 源程序可以在百度网盘自行下载&#xff0c;地址链接见下方。 链接&#xff1a;https://pan.b…

开源,微信小程序-超级计算器T3000 简介

笔者于四年前自学微信小程序开发&#xff0c;这个超级计算器T3000就是当时的练习作品。超级计算器T3000的功能有很多&#xff0c;其中的核心技术是矩阵计算&#xff0c;使用的工具库是math.js&#xff0c;其次是复杂运算和分式运算。关于math.js的使用&#xff0c;可以参考另一…

如何在极狐GitLab 配置 邮件功能

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了在极狐GitLab 用户…

图片标注编辑平台搭建系列教程(4)——fabric几何定制渲染

背景 标注的几何&#xff0c;有时需要一些定制化的渲染样式&#xff0c;例如&#xff0c;线中间展示箭头&#xff0c;表示方向。本期教程教大家如何实现fabric几何定制化渲染。 带箭头的线 fabric提供了一些原生的几何&#xff0c;例如Point、Polyline、Polygon。同时提供了…

LangChain入门:2.OpenAPI调用ChatGPT模型

引言 在本文中&#xff0c;我们将带您深入探索如何通过OpenAPI与ChatGPT模型进行高效交互&#xff0c;实现智能文本问答功能。通过LangChain库的实践&#xff0c;您将学习构建一个能够与用户进行自然语言对话的系统的关键步骤。 准备步骤 在动手编码之前&#xff0c;请确保您…

Collection与数据结构链表与LinkedList(三):链表精选OJ例题(下)

1. 分割链表 OJ链接 class Solution {public ListNode partition(ListNode head, int x) {if(head null){return null;//空链表的情况}ListNode cur head;ListNode formerhead null;ListNode formerend null;ListNode latterhead null;ListNode latterend null;//定义…

Beans模块之工厂模块DisposableBean

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…