初识算法 · 二分查找(4)

目录

前言:

寻找峰值

题目解析

算法原理

算法编写

寻找旋转排序数组中的最小值

题目解析

算法原理

算法编写

寻找缺失的数字

题目解析

算法原理

算法编写


前言:

​本文的主题是二分查找,通过三道题目讲解,一道是寻找峰值,一道是搜索旋转排序数组的最小值,一道是0 - n-1中缺失的数字。
链接分别为:
162. 寻找峰值 - 力扣(LeetCode)

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

LCR 173. 点名 - 力扣(LeetCode)
题目分为三个部分讲解,一是题目解析,二是算法原理,三是算法编写,那么,话不多说,直接进行主题咯。


寻找峰值

题目解析

题目是给了我们一个数组,这个数组并不像我们之前的数组一样具有明显的二段性,这个数组可以说是一个完全无序的数组,而我们要寻找的,是满足大于左右两值的数的索引,那么暴力解法简直就是不用经过大脑的,直接遍历数组即可,只要满足大于i - 1和 i + 1就可以了。

那么时间复杂度是显而易见的,直接就是O(N)了。

但是我们没有利用题目的条件,虽然是无序的,但是峰值的条件是大于左右两边,我们可以利用这个条件,使用二分查找。

算法原理

题目的隐含条件,左右两端都是负无穷的,数组可以有二段性,为:

我们随便定义一个位置,如果arr[i] > arr[i + 1]的话,那么在左区间一定是存在答案的,因为从num[-1]开始是负无穷,此时我们可以套用查找左端点的二分模板,对于右边的端点同理,如果arr[i] < arr[i + 1],代表右边有答案,因为nums[n]也是负无穷的。

所以我们就可以直接进入到算法编写了。

算法编写

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

所以,不是非要有序的才会存在二段性,像这种完全无序的,也是会存在二段性的。


寻找旋转排序数组中的最小值

题目解析

题目看起来非常复杂,但是实际上非常简单,无非就是介绍如何旋转数组介绍的多了一点而已,题目给的条件有原来是一个升序排序的数组,并且每个元素都不相同,要让我们找到一个最小的值。

要找最小的值还不简单吗?直接一个for循环遍历就可以了。

但是题目还要求了使用logN的算法解决该问题。那就是典型的使用二分咯。

如果使用的是暴力就是O(N)了。

算法原理

二分查找算法的原理都是需要看是否存在二段性,如果存在二段性的话,我们就可以使用二分查找算法了。

注意,最开始的数组是有序的,所以我们可以这样分数组:

而我们要找的,不就是C这个点吗!如果mid的值大于了D,也就是在AB段,我们就应该让left = mid + 1,如果mid 的值 < D,也就是可能命中我们要的答案,就让right = mid就好了。

那么这里有一个疑问,如果我们使用的参照物是A呢?

算法编写

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

这是参照物为D的情况,如果参照物是A的话:

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

如果参照物是A的情况,那么我们需要单独考虑数组是连续递增的情况,比如[1,2,3,4],如果参照物是A,也就是1,那么任意的数都会大于1,此时,left会一直++到4,最后返回的恰好是最大的而非最小的,那么这种情况,也就代表了数组没有经过旋转,所以直接返回nums[0]即可。


寻找缺失的数字

题目解析

题目要求非常简单,要求返回缺失的那个数字就可以了。

那这个题目虽然是简单难度,可是就非常有说法了。

什么说法呢?这道题可以有很多很多的解法。

比如我们可以直接遍历数组,如果前一个不等于后一个加一,就代表缺少了。

比如我们可以直接使用数学中的等差求和公式,减去整个数组的和就可以了。

比如我们可以使用位运算,利用^的特点,数^本身就是0,最后留下一个没有异或自己的数,从而找到。

比如我们可以利用哈希映射,将所有的值全部映射到一个数组里面,判断哪个数组的元素为0,也就可以返回对应的值了。

但是但是,以上的所有方法,四种方法都是O(N)的,并且哈希映射的方法还新开了一个空间,空间复杂度还是O(N)。就实际上来说都是比较慢的,我们可以利用二分查找来优化。

算法原理

算法原理,一问就是哪里去找二段性?

缺失的数字的左边,数组的元素都是等于数组的下标的,而缺失的数字的右边,数组的元素的下标都是不等于数组的元素的。而我们要的值是右边的左端点,所以left = mid + 1,right = mid,算法一下就明了了。

算法编写

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

唯一需要注意的就是,如果数组是0 1 2 3 ,代表缺失的数字是4,所以此时不存在右边的区间,此时left和nums[left]相等的,所以需要left  + 1。

二分查找的部分题目就先到这里了。


感谢阅读!

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

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

相关文章

【Web开发】什么是Nuxt? 利用Nuxt快速搭建前端项目

Nuxt官网&#xff1a;https://nuxt.com/ 启动一个Nuxt项目 在vscode的项目文件终端运行以下命令&#xff1a; npx nuxilatest init <my-app>npm installnpm run dev然后就启动了一个Nuxt项目 安装Nuxt UI Nuxt UI官网&#xff1a;https://ui.nuxt.com/ npx nuxilates…

线程的同步

目录 引入 认识条件变量 快速认识接口​编辑 认识条件变量​编辑 测试代码​编辑 生产消费模型 为何要使用生产者消费者模型 理解 编写生产消费模型 BlockingQueue 单生产单消费 多生产多消费 引入 同步&#xff1a;在保证数据安全的前提下&#xff0c;让线程…

【小白学机器学习22】 多变量分析,多变量回归(草稿)

目录 1 概念名词&#xff1a; 1.1 双变量分析与单因素分析 1.2 变化 1.3 相关分析 Correlation analysis 1.4 回归分析 Regression analysis 1.5 相干和相关 1.5.1 相干relevant 1.5.2 相关Correlation 2 双变量分析&#xff0c;也就是单因素分析 3 相关分析 4 正…

The database mes could not be exclusively locked to perform the operation.

当你尝试更改数据库名字时&#xff0c;如果遇到错误消息 "The database [database_name] could not be exclusively locked to perform the operation"&#xff0c;这意味着 SQL Server 无法获得对数据库的独占锁&#xff0c;因为该数据库当前正在被其他会话使用。这…

Hugging Face HUGS 加快了基于开放模型的AI应用的开发

在过去一年左右的时间里&#xff0c;开源人工智能模型在性能上已经明显赶上了 OpenAI、Google 和其他公司的流行闭源模型。 然而&#xff0c;由于在不同硬件上部署和维护这些模型所带来的开销&#xff0c;开发人员尚未广泛采用这些模型。为了解决这个问题&#xff0c;Hugging F…

驱动开发系列26 - Linux Graphics 调试 mesa 的 glDrawArrays (二)

目录 一:概述 二:Gallium3D 的工作流程 三:tc_draw_vbo 与 tc_call_draw_single 的关系: 四:tc_draw_vbo 与 tc_call_draw_single 的具体执行流程: 五:mesa中线程池设计介绍: 六:总结: 一:概述 众所周知,Mesa 的 Gallium3D 是一个图形驱动框架,它将图形管线…

【Unity】Unity中文本中插入超链接且可点击响应,TextMeshPro的进阶用法

一、需求和尝试 今天遇到这样一个需求&#xff1a;在文本中插入超链接&#xff0c;且这个链接可以点击跳转对应的url&#xff0c;具体形式如下图所示。 其实这个有一个简单粗暴的方法&#xff0c;就是把需要加超链接的文本单独拿出来&#xff0c;和其他文本进行拼接&#xf…

修改huggingface的缓存目录以及镜像源

执行以下语句查看当前配置 huggingface-cli env默认输出应该如下 (py39-transformers) PS D:\py_project\transformers_demo> huggingface-cli envCopy-and-paste the text below in your GitHub issue.- huggingface_hub version: 0.26.1 - Platform: Windows-10-10.0.22…

面向垂类场景的智能化低代码引擎

背景介绍 在通信领域中&#xff0c;不同客户的数字化场景存在多种个性化大屏的定制需求&#xff0c;常见业务范围涵盖政务、金融、教育、工业、传媒、互联网等行业领域。然而&#xff0c;面对如此巨大的产业痛点诉求&#xff0c;传统低代码领域却存在数据监控粒度不统一、定制化…

学习docker第三弹------Docker镜像以及推送拉取镜像到阿里云公有仓库和私有仓库

docker目录 1 Docker镜像dockers镜像的进一步理解 2 Docker镜像commit操作实例案例内容是ubuntu安装vim 3 将本地镜像推送至阿里云4 将阿里云镜像下载到本地仓库5 后记 1 Docker镜像 镜像&#xff0c;是docker的三件套之一&#xff08;镜像、容器、仓库&#xff09;&#xff0…

基于SpringBoot+Vue+MySQL的实践性教学系统

系统展示 用户前台界面 后台界面 系统背景 随着信息技术的快速发展&#xff0c;企业对于高效、智能的管理系统需求日益迫切。传统的管理系统大多采用单机版或C/S架构&#xff0c;存在操作复杂、维护困难、数据共享性差等问题。而基于SpringBootVueMySQL的全栈管理系统&#xff…

【10分钟本地部署大语言模型】借助1Panel、MaxKb、Ollama快速部署大语言模型(qwen、llama等)及知识库

前言&#xff1a; 本文介绍一种快速在Linux服务器&#xff08;windows使用wsl也可以&#xff09;上部署大语言模型&#xff08;含知识库&#xff09;的方式。 核心内容如下&#xff1a; 1Panel&#xff1a; 开源的Linux 服务器运维管理面板&#xff0c;通过该面板安装ollama和…

hivesql学习大纲

引言 - 简述Hive的用途和特点 - 为什么学习HiveSQL 第一部分&#xff1a;Hive基础 1.1 Hive简介 - 定义和架构 - Hive与传统数据库的区别 - Hive的应用场景 1.2 Hive环境搭建 - 所需环境和依赖 - 安装和配置Hive - 启动和停止Hive服务 1.3 Hive数据模型 - 数据库&#xff0…

STM32与ESP8266实现串口通信

在嵌入式系统设计中&#xff0c;经常需要将微控制器与Wi-Fi模块相结合&#xff0c;以实现无线通信功能。STM32是一款强大的微控制器&#xff0c;而ESP8266是一款流行的Wi-Fi模块。本文将详细介绍如何使用STM32通过串口与ESP8266实现通信&#xff0c;包括硬件连接、软件配置和代…

Serv00 免费虚拟主机 零成本搭建 PHP / Node.js 网站

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 Serv00 是一个提供免费虚拟主机的平台&#xff0c;包含了 3GB 的存储空间和 512MB 的内存空间&#xff0c;足够我们搭建一个 1IP 的小网站了。同时他还不限制每月的流量&#xff0c;并提供了 16 个数据库&…

进程间通信(一)管道

文章目录 进程间通信进程间通信概述进程间通信的方式管道通信示例--基于管道的父子进程通信示例--使用管道进程兄弟进程通信 管道的读写特性示例--不完整管道&#xff08;读一个写端关闭的管道&#xff09;示例--不完整管道&#xff08;写一个读端关闭的管道&#xff09; 标准库…

PyQt 入门教程(3)基础知识 | 3.1、使用QtDesigner创建.ui文件

文章目录 一、使用QtDesigner创建.ui文件1、创建.ui文件2、生成.py文件3、使用新生成的.py文件4、编辑新生成的.py文件 一、使用QtDesigner创建.ui文件 1、创建.ui文件 打开PyCharm&#xff0c;使用自定义外部工具QtDesigner创建mydialog.ui文件&#xff0c;如下&#xff1a; …

前端面试题-token的登录流程、JWT

这是我的前端面试题的合集的第一篇&#xff0c;后面也会更新一些笔试题目。秋招很难&#xff0c;也快要结束了。但是&#xff0c;不要放弃&#xff0c;一起加油^_^ 一、token的登录流程 1.客户端用账号密码请求登录 2.服务端收到请求&#xff0c;需要去验证账号密码 3.验证成…

大话网络协议:HTTPS协议和HTTP协议有何不同?为什么HTTPS更安全

大家现在访问网络,浏览网页,注意一下的话,网址前面基本上都是一个 https:// 的前缀,这里就是说明这个网址所采用的协议是 https 协议。那么具体应该怎么理解 https 呢? 本文我们就力争能清楚地解释明白这个我们目前应该最广的协议。 理解HTTP协议 要解释 https 协议,当…

[mysql]聚合函数GROUP BY和HAVING的使用和sql查询语句的底层执行逻辑

#GROUP BY的使用 还是先从需求出发,我们现在想求员工表里各个部门的平均工资,最高工资 SELECT department_id,AVG(salary) FROM employees GROUP BY department_id 我们就会知道它会把一样的id分组,没有部门的就会分为一组,我们也可以用其他字段来分组,我们想查询不同jb_id…