刷题训练之二分查找

news2024/11/22 19:34:11

> 作者:დ旧言~
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:熟练掌握二分查找算法

> 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。

> 专栏选自:刷题训练营

> 望小伙伴们点赞👍收藏✨加关注哟💕💕 

🌟前言分析

        最早博主续写了牛客网130道题,这块的刷题是让同学们快速进入C语言,而我们学习c++已经有一段时间了,知识储备已经足够了但缺少了实战,面对这块短板博主续写刷题训练,针对性学习,把相似的题目归类,系统的刷题,而我们刷题的官网可以参考:​​​​​​

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

而今天我们的板块是二分查找。

⭐知识讲解

很多小伙伴们在想二分查找嘛,只有升序或者是降序的数字里面查找,有这个想法的是大错特错的,在一些题目中有些无序也可以使用二分查找,所以说二分查找的知识点没有我们想的那么简单,在二分查找中我们会总结一些模板,这些模板要死记硬背要理解哦,题目选取的很多,大家不要跳过一些题目,有些题目是为后面的题目做铺垫的,望大家可以从头看到尾,这里就简单的总结一些二分查找的知识点:

  • 二分查找的时间复杂度:log(N)
  • 二分查找的范围:有序的数组或者无序

⭐经典题型

 🌙topic-->1

题目链接:1. 二分查找 - 力扣(LeetCode)

 

题目分析:

 在一个有序的数组中查找一个数字  target  ,如果存在就返回数组的下标,没有的话就返回-1

算法原理:

  • 解法一:

暴力遍历数组,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

图解:

细节:

  1. 防止 mid 超过整形最大值
  2. 循环的条件是 left <= right

代码演示:

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;
        }
        // 没有返回-1
        return -1;
    }
};

 模板总结:


        // 定义左右指针
        int left = 0,right = nums.size() - 1;
        // 循环
        while(left <= right) // 细节二
        {
            // int mid = left + (right - left + 1) / 2 等价
            int mid = left + (right - left) / 2;// 细节一
            if(....)
                left = mid + 1;
            else if(....)
                right = mid - 1;
            else
                return ...;
        }

🌙topic-->2

题目链接:2.二分查找力扣(LeetCode)

题目分析:

在一个非递归中找一个等于 target 下标,如果没有就返回 {-1,-1}

算法原理:

  • 解法一:

暴力遍历数组,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution
{
public:
	vector<int> searchRange(vector<int>& nums, int target)
	{
        // 定义左右指针
        int left = 0,right = nums.size() - 1;
        // 处理空数组
        if(nums.size() == 0)
            return {-1,-1};
        int begin = 0;// 定义左边界
        // 去除左边界的元素
        while(left < right) // 细节一
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] < target)
                left = mid + 1;// 细节二
            else
                right = mid; 
        }
        // 判断是否有值
        if(nums[left] != target)
            return {-1,-1};
        else 
            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;// 细节四 
        }
         // 返回
        return {begin,right};
    }

};

 模板总结:

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

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

// 下面出现 -1 的时候,上面就加 +1

🌙topic-->3

这道题目就不再讲解的这么细了,具体还得琢磨第二道题目:

题目链接:3.二分查找  - 力扣(LeetCode)

题目分析:

给定一个排序数组(升序)和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

算法原理:

  • 解法一:

暴力遍历数组,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution {
public:
    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;
        }
        // 判断
        if(nums[left] < target)
            return right + 1;
        return right;
    }
};

 🌙topic-->4

这道题目就不再讲解的这么细了,具体还得琢磨第二道题目:

题目链接:4.二分查找  - 力扣(LeetCode)

 

题目分析:

求 X 的算数平方根,结果保留整数。

算法原理:

  • 解法一:

暴力举例1 2 3 .... x,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution {
public:
    int mySqrt(int x) 
    {
        // 处理
        if(x < 1) return 0;
        // 定义两个指针
        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 left;
    }
};

  🌙topic-->5

这道题目就不再讲解的这么细了,具体还得琢磨第二道题目:

题目链接:5.二分查找  - 力扣(LeetCode)

  

题目分析:

有一个山峰数组(数组有递增和递减),返回数组中峰顶的下标。

算法原理:

  • 解法一:

暴力遍历数组就可以了,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) 
    {
        // 定义两个指针
        int left = 1,right = arr.size() - 2;
        // 循环
        while(left < right)
        {
            int mid = left + (right - left + 1) / 2;
            if(arr[mid] > arr[mid - 1]) left = mid;
            else right = mid - 1;
        }
        return left;
    }
};

   🌙topic-->6

这道题目就不再讲解的这么细了,这里和第五道题目几乎一样:

题目链接:6.二分查找  - 力扣(LeetCode)

  

题目分析:

有一个山峰数组,这个山峰数组有多个山峰,只要返回其中一峰顶就行(返回数组中峰顶的下标)

算法原理:

  • 解法一:

暴力遍历数组就可以了,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

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

   🌙topic-->7

这道题目就不再讲解的这么细了,具体还得琢磨第二道题目:

题目链接:7. 二分查找- 力扣(LeetCode)

  

题目分析:

在一个数组中找最小值。

算法原理:

  • 解法一:

暴力遍历数组就可以了,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution
{
public:
	int findMin(vector<int>& nums)
	{
		int left = 0, right = nums.size() - 1;
		int x = nums[right]; // 标记⼀下最后⼀个位置的值
		while (left < right)
		{
			int mid = left + (right - left) / 2;
			if (nums[mid] > x) left = mid + 1;
			else right = mid;
		}
		return nums[left];
	}
};

 🌙topic-->8

这道题目就不再讲解的这么细了,具体还得琢磨第二道题目:

题目链接:8.二分查找  - 力扣(LeetCode)

  

题目分析:

在一个  0 ~  n-1  数组中找缺少的数字。

算法原理:

  • 解法一:

暴力遍历数组就可以了,时间复杂度为O(n)。

  • 解法二:

采用二分查找,二分算法原理博客,这里如果不会二分查找的小伙伴们大家可以看看这篇博客,这里我们再讲解一下解法二的算法原理。

代码演示:

class Solution {
public:
    int takeAttendance(vector<int>& records) {
        int missingNumber(vector<int>&nums)
        {
            int left = 0, right = nums.size() - 1;
            while (left < right)
            {
                int mid = left + (right - left) / 2;
                if (nums[mid] == mid) left = mid + 1;
                else right = mid;
            }
            return left == nums[left] ? left + 1 : left;
        }
    }
};

 🌟结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

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

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

相关文章

计算IP地址总个数的方法及其应用

IP地址是计算机网络中用于唯一标识和定位设备的数字地址&#xff0c;是Internet Protocol&#xff08;IP&#xff09;的核心组成部分。计算IP地址的总个数是网络规划和管理中的重要任务之一&#xff0c;本文将介绍计算IP地址总个数的方法及其应用。 IP地址查询&#xff1a;IP数…

STM32 学习13 低功耗模式与唤醒

STM32 学习13 低功耗模式与唤醒 一、介绍1. STM32低功耗模式功能介绍2. 常见的低功耗模式&#xff08;1&#xff09;**睡眠模式 (Sleep Mode)**:&#xff08;2&#xff09;**停止模式 (Stop Mode)**:&#xff08;3&#xff09;**待机模式 (Standby Mode)**: 二、睡眠模式1. 进入…

基于CAPL的BIN文件解析

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

管理 Python 项目的艺术:在 PyCharm 中使用虚拟环境(以BPnP为例)

在 PyCharm 中使用虚拟环境对于 Python 项目开发具有多方面的重要作用&#xff0c;这些作用体现在提升项目管理的效率、保障代码的可运行性以及维护项目的长期稳定性等方面。以下是使用虚拟环境的几个关键好处&#xff1a; 1. 依赖管理和隔离 虚拟环境允许每个项目拥有…

Adobe Photoshop CC 2017无法打开解决方案

Adobe Photoshop CC 2017双击无反应&#xff0c;右键以管理员身份运行也没有反应 解决方案&#xff1a; 事件查看器中查看应用程序的事件 如果找到程序报错事件&#xff0c;网上下载ZXPSignLib-minimal.dll文件替换错误模块路径位置的该文件即可 ZXPSignLib-minimal.dll下载地…

20240423-bitlocker加密怎么解除

20240423-bitlocker加密怎么解除 2024/4/23 15:42 百度&#xff1a;bitlocker加密怎么解除 https://baijiahao.baidu.com/s?id1779469107112180136&wfrspider&forpc Bitlocker加密怎么解除 解除BitLocker加密的步骤如下&#xff1a; 打开“控制面板”&#xff1a;在…

重学java 20.面向对象 继承 下

对未来真正的慷慨&#xff0c;是把一切献给现在 —— 24.4.22 super和this 学习目标&#xff1a; 01.继承中构造方法的特点 02.super和this的具体使用 03.继承的特点 04.练习&#xff1a;为父类中private属性赋值 一、继承中构造方法的特点 1.注意&#xff1a; 在new子类对象时…

项目开发过程中的错误记录

一、VUE版本一致但是运行不起来。 管理员运行命令提示符 切换到可以看到package.json的目录下面 npm install --registryhttps://registry.npmmirror.com npm install npm run dev 二、git pull拉取不下来远程项目 三、ssm项目运行时&#xff0c;tomcat输出日志乱码 解决&am…

红黑树封装map和set(模拟实现)

troop主页 临近五一放假&#xff0c;祝大家节日快乐&#xff0c;我们的学习还在路上&#xff01;&#xff01; 在前面一章我们已经实现出了红黑树的基本框架&#xff0c;现在我们要有这个底层结构去封装map和set。 一 红黑树的迭代器 但在这之前我们要先把红黑树的迭代器实现出…

SRS WebRTC Whip 和 Whep 部署体验问题

whip 報錯 404 webrtc推流 小窗口一闪而过&#xff0c;然后查看f12回复404的报错信息 chrome版本&#xff1a; 正在检查更新 版本 123.0.6312.123&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; centos 7.9 源码安装部署&#xff0c; 代码分支5.0 完全按…

linux /openEuler/annocanda/SecretNote

国产操作系统欧拉&#xff08;EulerOS&#xff09;是华为公司自主研发并推广的开源操作系统。它基于Linux内核&#xff0c;旨在为各种设备提供统一的操作系统平台&#xff0c;从而为用户提供更加流畅、安全、可靠和智能的使用体验。 linux 中安装annocanda : Anaconda3-2024.0…

逆向修改app就可以游戏充值到账?

hello ,大家好, 现在市场仍然流行着非常多的传奇类游戏私服或者其他类型的游戏私服,随着私服越来越多(很多并不合法),越来越多的人加入了破解,逆向修改,或者代充的队伍并从中获利。这里我给大家分享一下这些做代充的常规的做法,以及大家作为游戏服务器如何避坑做强校验…

《LINUX运维从入门到精通 》:运维入门者的自学用书

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 写在前面 《Linux运维从入门到精通》从初学者角度…

NCF29A1 高端阻抗匹配

一、前言 Class E 高端 L-Front 匹配集成了额外的滤波器&#xff0c;提供了足够的谐波衰减&#xff0c;使 NCF29A1 与天线在比基频更高的频率下具有相当大的增益。向 PA 提供的阻抗和输出电容与表 1 ZPAOUT 所示相同。 二、原理图 图 1 高端 L-Front 匹配原理图 1&#xff…

【数据结构】AVL树(万字超详细 附动图)

一、前言 二、AVL树的性质 三、AVL树节点的定义 四、AVL树的插入 五、AVL树的平衡调整 六、AVL树的验证 6.1 验证有序 6.2 验证平衡 七、AVL树的删除 八、AVL树的性能和代码 一、前言 还没有学习过二叉搜索树的同学可以移步 【数据结构】二叉搜索树-CSDN博客https:/…

Acrobat Pro DC 2021:强大的PDF编辑软件

Acrobat Pro DC 2021是Adobe公司推出的一款全面而强大的PDF编辑软件&#xff0c;凭借其卓越的性能和丰富的功能&#xff0c;成为了PDF编辑领域的领军者。 Acrobat Pro DC 2021中文激活版下载 这款软件具备全面的PDF编辑功能&#xff0c;包括文本编辑、图片处理、页面组织等&…

Vue3引入高德地图js API 2.0

文章目录 前言一、地图加载1.本文准备环境2.引入库3.加载地图4.加载地图控件 二、POI搜索1.什么是poi搜索2.如何使用 三、绘制点标记与信息窗体1.场景描述2.案例3.信息窗体-链接路由跳转4.进阶-通过Marker自动触发标记点&#xff08;非鼠标手动点击&#xff09; 四、jsApi地图事…

指挥中心实战指挥平台-通信指挥类装备多链路聚合设备解决方案实例

一、建设目标及要求 坚持“一切为了实战、一切围绕实战、一切服务实战”的总要求&#xff0c;紧紧围绕大数据应用和自动化、智能化、智慧化这一主题主线&#xff0c;建设升级改造支队指挥中心&#xff0c;集成语音、视频、即时消息、短信、对讲、会议等多媒体通信能力&#xf…

AJAX——图片上传

图片上传流程 1.获取图片文件对象 2.使用FormData携带图片文件 3.提交表单数据到服务器&#xff0c;使用图片url网址 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible"…

埋点,自己写插件,自己写的按钮埋点,掘金同款投递简历

20分钟掌握 Vite 插件开发 - 掘金 vite的生命周期啥的 1.浏览器的控制台输出有样式的字 // const randomLetterPlugin ()>{ // const letters [wwwwwww,000000000000,888888888888]; // //随机获取一个字符并打印 // const printRandomLetter ()>{ // …