当前位置: 首页 > news >正文

【二分查找】--- 进阶题目赏析

 Welcome to 9ilk's Code World

       

(๑•́ ₃ •̀๑) 个人主页:         9ilk

(๑•́ ₃ •̀๑) 文章专栏:      算法Journey


本篇博客我们继续来了解一些有关二分查找算法的进阶题目。


🏠 寻找峰值

📌 题目内容

162. 寻找峰值 - 力扣(LeetCode)

📌 题目解析

  • 与山脉数组那道题不同的是,本题数组内存在多个峰值。
  • 注意本题一个规定,即num[-1] = num[n] = 负无穷,数组边界都是最小负无穷。

📌算法原理

📒  思路一:暴力解法

有三种情况下,某个数是峰值,我们暴力解法只需要遍历一遍数组进行分类情况即可,但是时间复杂度是O(N)不符合题意。

📒 思路二:二分查找

我们发现:

1. 当arr[i] > arr[i+1]时,此时左边区域一定存在峰值,因此我们要向左缩小范围。

2.当arr[i] <  arr[i+1]时,此时右边区域一定存在峰值,因此我们要向右缩小范围。

3.由于峰值位置的不确定我们需要寻找峰值,因此在寻找峰值的过程中,我们发现了二段性因此可以使用二分查找

二分过程:

1. arr[i] > arr[i+1]  --->  right = mid , 此时mid处可能就是峰值所以不能跳过mid。

2. arr[i] < arr[i+1]  --->  left   = mid +1 ,此时mid+1处才可能是峰值,因此可以跳过mid。

参考代码:

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

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

📌 题目内容

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

📌 题目内容

  • 注意题目数组中的数字各不相同。

📌算法原理

📒 思路一:暴力解法

暴力解法思路很简单,可以定义一个min变量,遍历一遍数组,遇到比他小的就更新min,时间复杂度是O(N),并不符合题目要求。

📒 思路二:二分查找

题目要我们找旋转排序数组中的最小值,这个位置是“确定”的,整个数组的大小变化趋势如上图。以D为参考点,我们发现:

1.  最小值所在位置的左边,都是严格大于等于数组最后一个数的。

2.最小值所在位置的右边,都是小于等于数组最后一个数的。

3.本题要我们求的很明显地划分了两段区间,体现了二段性,我们要做的是思考如果mid落在划分的两段区间内,我们如何靠近目标

二分流程:

1. 当nums[mid] > nums[n-1]时,说明mid处于AB段,此时我们需要向右缩小范围,left = mid+1.

2.当nums[mid] <= nums[n-1]时,说明mid位于CD段,此时我们需要向左缩小范围,由于目标在CD段上,因此更新right时我们不能跳过mid因为mid可能就是最小值

参考代码:

class Solution {
public:int findMin(vector<int>& nums) {int  left = 0;int 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];  }};

思考:我们划分两端区间是以D为参考点,那么我们是否能以A为参考点呢?

1. A~B段是大于等于nums[0](A点)的,而C~D段是严格小于nums[0]的。

2.此时二分流程:

A - B : nums[i]>=nums[0] --> left= mid +1;
C - D : nums[i] < nums[0] --> right = mid;
3.当旋转数组旋转到原来升序时:

此时A点就是最小值,区间不断向右,此时就会丢掉最小值,因此对于这种边界情况我们需要特殊处理。

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

🏠 0~n-1中缺失的数字

📌 题目内容

LCR 173. 点名 - 力扣(LeetCode)

📌 题目内容

  • 注意:对于[0,1,2,3,4]这样的数组,此时缺失的数字应该为5.

📌算法原理

📒 思路一:哈希表

由于缺了一个数字,因此总的人数为数组元素个数+1,此时我们先遍历一遍数组进行映射,再从0-N遍历,没有映射的就是缺失的数字。

class Solution {
public:int takeAttendance(vector<int>& records) {unordered_map<int,int> mp;for(const auto& e : records){mp[e]++;}int reasult = 0;int n = records.size() + 1; for(int i = 0 ; i < n ; i ++){if(mp[i] == 0){reasult = i;break;}}return reasult;}
};

📒 思路二:直接遍历找结果

由于学号从0开始,因此数组中每个数都应该与下标相同,由于缺失了一个数,可能导致它的下一个数占它的位置,也可能他就是最后一个数。

class Solution {
public:int takeAttendance(vector<int>& records) {bool flag = false;int i = 0;for( i = 0 ; i < records.size();i++){if(i != records[i]){flag = true;break;}}return i;}
};

📒 思路三:位运算

既然知道应到同学的人数n,又根据按位异或a^a = 0 的性质,我们可以用ret遍历一遍数组进行异或,再从0-N异或,最后ret就是缺失的数字。

class Solution {
public:int takeAttendance(vector<int>& records) {int n =  records.size();int sum = 0;for(int i = 0 ;i <= n ;i++){sum ^= i;}for(int i = 0; i < records.size();i++){sum ^= records[i];}return sum;}
};

📒 思路四:高斯求和公式

由于我们知道了应到学生人数,因此我们可以用等差数列求原本应该的学号之和,再遍历数组减去,最后得到的就是缺失的数字。

class Solution {
public:int takeAttendance(vector<int>& records) {int n =  records.size() + 1;int sum = 0 + (n*(n-1)) / 2;cout << sum <<endl;for(int i = 0; i < records.size();i++){sum -= records[i];}return sum;}
};

📒 思路五:二分查找

前面的思路都很简单,但时间复杂度都是O(N)。仔细观察我们发现因为缺失了数字,会造成二段性。

我们发现,由于缺失了一个数字造成了二段性:

1. 左边一段区间的值都与下标相同,而右边一段区间的值与下标不匹配,因此我们需要去靠近第一个不与下标匹配的值。此时这个值的下标就是缺失的数字。

2.nums[mid] = mid时,说明mid在左边,此时需要向右缩小范围。

3.nums[mid] ≠ mid时,说明mid在右边,此时mid可能就是我们要找的,因此不能跳过mid.

4.需要注意的是对于类似[0,1,2,3,4]这样的情况,最后left==right时,我们需要返回left+1.

参考代码:

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

总结:

1. 当题目很明确要求的目标能划分二段性时,我们需要考虑的是在划分区间内怎么接近目标。

2.当不是很明确二段性时,我们要考虑的是在找目标的过程中能否发现二段性。

相关文章:

【二分查找】--- 进阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Journey 本篇博客我们继续来了解一些有关二分查找算法的进阶题目。 &#x1f3e0; 寻找峰值 &#x1f4cc; 题目内容 162. 寻找峰值 - 力扣&#…...

CSS 对齐

CSS 对齐 在网页设计中&#xff0c;CSS&#xff08;层叠样式表&#xff09;对齐是一种基本而重要的技术&#xff0c;它决定了网页元素的位置和布局。CSS 提供了多种对齐方法&#xff0c;可以精确控制元素的水平、垂直对齐&#xff0c;以及相对于其父元素或整个页面的位置。本文…...

暑假算法刷题日记 Day 10

目录 重点整理 054、 拼数 题目描述 输入格式 输出格式 输入输出样例 核心思路 代码 055、 求第k小的数 题目描述 输入格式 输出格式 输入输出样例 核心思路 代码 总结 这几天我们主要刷了洛谷上排序算法对应的一些题目&#xff0c;相对来说比较简单 一共是13道…...

【Midjourney】AI作画提示词工程:精细化技巧与高效实践指南

文章目录 &#x1f4af;AI作画提示词基础结构1 图片链接1.1 上传流程 2 文字描述3 后置参数 &#x1f4af;AI作画提示词的文字描述结构1 主体主体细节描述2 环境背景2.1 环境2.2 光线2.3 色彩2.4 氛围 3 视角4 景别构图5 艺术风格6 图片制作方法7 作品质量万能词 &#x1f4af;…...

C语言——文件

文件操作 概念 文件是指存储在外存储器上&#xff08;一般代指磁盘&#xff0c;也可以是U盘&#xff0c;移动硬盘等&#xff09;的数据的集合。 文件操作体现在哪几个方面 1.文件内容的读取 2.文件内容的写入 数据的读取和写入可被视为针对文件进行输入和输出的操作&#xf…...

视频孪生技术在智慧水利(水务)场景中的典型应用展示

一、智慧水利建设规划 根据水利部编制《“十四五”智慧水利建设规划》&#xff0c;建设数字孪生流域、“2N”水利智能业务应用体系、安全可控水利网络安全防护体系、优化健全水利网信保障体系&#xff0c;建成七大江河数字孪生流域&#xff0c;推进水利工程智能化改造&#xf…...

使用kubekey快速搭建k8s集群

项目仓库地址 https://github.com/kubesphere/kubekey/ 支持的Kubernetes Versions https://github.com/kubesphere/kubekey/blob/master/docs/kubernetes-versions.md 安装 选择自己想要下载的版本 https://github.com/kubesphere/kubekey/releases 复制下载链接并下载 示…...

C++——入门基础(上)

目录 一、C参考文档 二、C在工作领域的应用 三、C学习书籍 四、C的第一个程序 五、命名空间 &#xff08;1&#xff09;namespace的定义 (2)命名空间的使用 六、C的输入和输出 七、缺省函数 八、函数重载 九、写在最后 一、C参考文档 &#xff08;1&#xff09;虽…...

Spring事务失效

类内部访问导致事务不生效原因&#xff1a; 注解Transaction的底层实现是Spring AOP技术&#xff0c;而Spring AOP技术使用的是动态代理。spring事务失效的原因就是动态代理失效的原因: 对于static方法和非public方法&#xff0c;注解Transactional是失效的&#xff0c;因为不…...

Qt QLabel标签制作弹框效果,3s后缓慢自动消失

效果图 初始化说明 void InitStatusTips() {if (NULL statusTips_) {return;}statusTips_->setFixedSize(300, 80);//固定大小statusTips_->move((width() - statusTips_->width()) / 2, height() - 30 - statusTips_->height());//移动位置statusTips_->setA…...

JZ55 二叉树的深度

二叉树的深度_牛客题霸_牛客网 递归代码太简单-一行就可以,可以用二叉树的层序遍历&#xff0c;顺便温习下二叉树层序遍历的写法。 对应leetcode 104题&#xff0c;层序遍历对应leetcode-102自顶向下&#xff0c;leetcode-107自底向上 /* struct TreeNode {int val;struct Tre…...

视频号分销系统搭建教程,源代码+部署上线指南

目录 一、视频号分销是什么&#xff1f; 二、视频号分销系统怎么搭建&#xff1f; 1.系统架构设计 2.部署与上线 3.持续迭代与升级 三、部分代码展示 一、视频号分销是什么&#xff1f; 视频号分销系统是合集了视频号商家的产品&#xff0c;推广达人推广商家的产品可赚取…...

【python】cryptography库学习

【python】cryptography库学习 cryptography学习1-安装2-cryptography学习2.1-fernet的使用2.2-padding填充2.3-Hash2.4-ciphers&#xff08;对称算法AES为例&#xff09;2.5-asymmetric(非对称算法RSA为例)函数&#xff1a;generate_private_key类&#xff1a;RSAPrivateKey&a…...

解密!抖音百万粉丝博主三维地图视频都用到了什么GIS数据和技术

引言 在抖音上有许多诸如三维地图科普局、三维地图看世界和三维地图鉴赏等百万粉丝博主靠着三维地图科普城市、景区、人文和地理视频获赞百万&#xff0c;在我们浏览视频时犹如身临其境一般&#xff0c;那么制作这些视频需要什么GIS技术呢&#xff1f;如何利用MapMost技术自己…...

Python知识点:如何使用Kubernetes与Python进行容器编排

Kubernetes 是一个开源的容器编排平台&#xff0c;用于自动化容器化应用的部署、管理和扩展。结合 Python&#xff0c;你可以通过 Kubernetes API 和工具&#xff0c;如 kubectl 和 kubernetes-client 库&#xff0c;来编写和管理容器化应用。以下是如何使用 Kubernetes 和 Pyt…...

Markdown与Word中插入图片的方法及比较

在撰写文档时&#xff0c;无论是技术文档、博客还是学术论文&#xff0c;插入图片都是非常常见的需求。本文将对比两种流行的文本编辑工具——Markdown和Microsoft Word——在插入图片方面的异同点。 Markdown插入图片 如何插入图片 在Markdown中插入图片非常简单&#xff0…...

Vue3+Vite安装配置tailwindCss

考虑到官网不是很好访问&#xff0c;这里记录一下简单步骤方便小友查阅 1. 安装依赖 npm install -D tailwindcss postcss autoprefixer2. 初始化配置文件 npx tailwindcss init -p3.配置模板路径 /** type {import(tailwindcss).Config} */ export default {content: [&quo…...

大数据学习-Spark基础入门

一、Spark是什么&#xff1f; Stack Overflow的数据可以看出&#xff0c;2015年开始Spark每月的问题提交数量已经超越Hadoop&#xff0c;而2018年Spark Python版本的API PySpark每月的问题提交数量也已超过Hadoop。2019年排名Spark第一&#xff0c;PySpark第二&#xff1b;而十…...

C语言:链表插入

链表的插入分为头插入&#xff0c;中间插入和尾插入。 具体方法如下&#xff1a; #include<stdio.h> #include<stdlib.h>typedef struct node {int s;struct node* pnext; }list;list* addnode(list** pphead, list** ppend, int n) {list* ptemp malloc(sizeof…...

xss 一些例子

目录 XSS 1.Ma Spaghet!​编辑 2.Jefff​编辑 3.Ugandan Knuckles​编辑 4.Ricardo Milos​编辑 5.Ah Thats Hawt​编辑 6.Ligma​编辑 7.Mafia​编辑 简单解法就是换一个函数 作者得原意解法 8.Ok, Boomer​编辑 XSS 1.Ma Spaghet! 这里接收了一个somebody参数&…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

论文阅读:Matting by Generation

今天介绍一篇关于 matting 抠图的文章&#xff0c;抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法&#xff0c;已经有很多的工作和这个任务相关。这两年 diffusion 模型很火&#xff0c;大家又开始用 diffusion 模型做各种 CV 任务了&am…...