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

【LeetCode 算法专题突破】---二分查找(⭐⭐⭐)

前言

我在算法题目的海洋中畅游已久,也曾在算法竞赛中荣获佳绩。然而,我发现自己对于算法的学习,还缺乏一个系统性的总结和归类。尽管我已经涉猎过不少算法类型,但心中仍旧觉得有所欠缺,未能形成完整的算法体系。

因此,我决定踏上这次算法之旅,对常见的算法进行一次全面的梳理与归类。我希望通过这个过程,能够更深入地理解每个经典算法类型的核心知识,加强我的算法能力,并完善自己的算法体系。

同时,我也希望能够将这次学习的成果与你分享,希望对你也有所帮助。让我们一同在算法的世界里探索、成长,共同迎接未来的挑战吧!

1.经典的不能在经典的二分查找(难度⭐)

Leetcode链接:704. 二分查找

1.1题目描述:

     这是一道非常典型的二分查找算法题目,可以说所有要学习二分查找算法的人都必须掌握这道题。题目要求很简单,就是在一个有序数组中查找目标值target。这道题是二分查找算法的入门题和模版题,没有掌握这道题就无法开始学习更复杂的二分查找算法题目。所以这道题对于二分查找算法的理解和掌握非常关键和必要。

1.2代码:

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

通过这道二分查找的典型题,我对二分查找算法的理解更进一步:

我对二分查找的区间划分有了更深的理解:

  • 当mid位置的值小于target时,证明左区间[left, mid-1]都不可能存在target,所以左区间变为[mid+1, right]。
  • 当mid位置的值大于target时,证明右区间[mid+1, right]都不可能存在target,所以右区间变为[left, mid-1]。
  • 当mid位置的值等于target时,就找到了目标值。

我理解到二分查找的本质就是通过比较中间mid值与target的值,可以排除一半的搜索区间,使搜索范围越来越小,直到找到target。

通过这道题我对二分查找算法模板有了更加熟练的掌握,可以应用到其他二分查找题目中去。

2.在排序数组中查找元素的第一个和最后一个位置(难度⭐⭐)

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

2.1题目描述:

2.2代码:

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1, begin = -1, end = -1, mid;//找到区间左边界while(left<=right){mid = (left + right)/2;if(nums[mid] > target){right = mid - 1;}else if(nums[mid] < target){left = mid + 1;}else{begin = mid;right--;//right区间左移,使得mid左移,直到到达左区间边界,此时right正好和left重合}}left = 0, right = nums.size() - 1;//找到区间有边界while(left<=right){mid = (left + right)/2;if(nums[mid] > target){right = mid - 1;}else if(nums[mid] < target){left = mid + 1;}else{end = mid;left++;//left区间右移,使得mid右移,直到到达又区间边界,此时left正好和right重合}}return {begin,end};}
};

这道题的大思路和上面的题并没有太大区别,只是为了找到左右区间,需要两次二分查找

具体来说,在求左右区间边界时,处理mid==target的情况需要进行特别考虑:

  • 求左区间边界时,需要在记录begin索引后,继续将right索引左移,使得mid向左逼近,直到不等于target时才能锁定左区间边界。
  • 求右区间边界时,需要在记录end索引后,继续将left索引右移,使得mid向右逼近,直到不等于target时才能锁定右区间边界。

这种细微的逻辑调整体现了二分查找的灵活性,在保持模板框架不变的情况下,通过简单逻辑修改就可应对新的问题。

3. 有效的完全平方数(难度⭐)

Leetcode链接:367. 有效的完全平方数

3.1题目描述:

撇开具体问题不讨论,假设需要找到完全平方数,你可能会采用这样的方法:将原数进行二分,然后将得到的中间值平方,观察是否等于目标值。如果相等,那么找到了完全平方数;如果不等,就可以根据大小关系缩小搜索范围,继续二分。为什么选择这种方式呢?因为这种方法的效率相对较高。既然如此,我们为何不考虑运用二分法来解决这类问题呢?

3.2代码:

class Solution {
public:bool isPerfectSquare(int num) {long long left = 0, right = num, mid = 0;long long s;while(left<=right){mid = (left + right)/2;s = mid * mid;if(s>num){right=mid-1;}else if(s<num){left=mid+1;}else{return true;}}return false;}
};

在这个解决方案中,我们并没有深入探讨具体的代码细节,只是简单地将二分算法应用于这个场景。然而,通过这个简单的经验,我们可以得出一个更加广泛的启示:如果今后遇到类似的问题,我们可以考虑运用二分法。

4.寻找峰值(难度⭐⭐)

二分熟练度up up up~

Leetcode链接:162. 寻找峰值

4.1题目描述:

在面对这个问题时,我们甚至没有提供目标值(target),而且输入序列并不保证是有序的。这是否意味着我们可以应用二分查找算法呢?
让我们尝试通过代码来展示这一思路,看看是否能够在这样的条件下成功运用二分查找的思想解决问题。

4.2代码:

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

初看之下,面对问题好像难以着手,但让我们仔细分析一下,看看能否找到解决方案。

题目要求在数组中找到任意一个峰值,那么我们可以考虑将数组分为两个区间:一个是递增区间,另一个是递减区间。峰值实际上是这两个区间的交界点。

假设我们随机选择一个点进行比较,如果它比右侧位置的值小,说明它在一个递增的区间;反之,如果它比右侧位置的值大,说明它在一个递减的区间。

基于这个性质,我们可以运用二分算法。当 nums[mid] < nums[mid+1] 时,表示在一个递增区间,峰值必定在 mid+1 及其之后的位置;而当 nums[mid] > nums[mid+1] 时,表示在一个递减区间,峰值可能在 mid 或其之前的位置(需要注意,峰值有可能就是在 mid 位置)。

因此,我们更新 right = mid,而不需要进行 -1 的操作。由于不需要 -1,当 left == right 时,如果已经找到峰值,我们应该如何退出循环呢?

这里可以进行特殊处理,或者将循环条件改成 left < right。在某些情况下,模板并不是固定不变的,我们可以根据实际情况进行调整。通过解决这道题,我们不仅学到了一些技巧,也积累了宝贵的经验。

5.寻找旋转排序数组中的最小值(难度⭐⭐)

Leetcode链接:153. 寻找旋转排序数组中的最小值

5.1题目描述:

这题的解题思路与前面一道问题相似,我们需要根据所给的条件找到一个可以进行比较的参照物或者说参照系。让我们来审视一下具体的代码。

5.2代码:

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

考虑到题目给出的是一个经过旋转的升序数组,这使得数组不再是有序的,我们需要思考如何运用二分法来解决这一问题。

观察到,经过旋转的升序数组可以分为两个递增的区间,一个较大的区间和一个较小的区间。我们可以以区间的最大值作为参照物来进行分析。

以最右边的元素为例,它可能是小区间的最大值,也可能是大区间的最大值。如果它是大区间的最大值,这就意味着数组没有经过旋转,因此我们可以先忽略这种特殊情况(这是一个解题的小技巧,特殊情况可以后续再处理)。

题目要求找到最小的元素,即小区间的最小值。因此,我们需要找到小区间,并在其中找到最小元素。具体操作如下:

  • 当 nums[mid] > nums[n] 时,表示中间位置 mid 处于大区间,因此将 left 调整为 mid + 1;
  • 当 nums[mid] < nums[n] 时,表示中间位置 mid 处于小区间,因此将 right 调整为 mid。注意,这里不能减1,因为我们要找的值在小区间内,不能排除掉中间元素。
  • 接着,考虑特殊情况,即当 nums[mid] < nums[n] 时,数组的最右元素 n 是大区间的最大值。如果我们让 right = mid,会导致最终循环结束时出现 left = right 的情况。为了避免这种情况,我们将循环的条件调整为 left < right。

这道题是二分法的一个变式,关键在于找到以何为参照系来确定区间的位置,一旦确定,后续的工作就变得相对容易。

6.点名(难度⭐)

Leetcode链接:LCR 173. 点名

6.1题目描述:

这道题我其实一开始也想不出来,选这道题的目的其实也是想说明,算法积累的重要性,见多识广,才能思路开阔,临危不乱。

6.2代码:

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

总结一下:

完成了这六道题目后,相信你对二分查找已经得心应手了~

接下来,继续努力,迎接新的挑战吧~

如果有一天觉得对二分有些生疏了,不妨回来再刷一遍,巩固一下技能~

最后,祝愿你未来的刷题之路愉快顺利~

相关文章:

【LeetCode 算法专题突破】---二分查找(⭐⭐⭐)

前言 我在算法题目的海洋中畅游已久&#xff0c;也曾在算法竞赛中荣获佳绩。然而&#xff0c;我发现自己对于算法的学习&#xff0c;还缺乏一个系统性的总结和归类。尽管我已经涉猎过不少算法类型&#xff0c;但心中仍旧觉得有所欠缺&#xff0c;未能形成完整的算法体系。 因…...

一个简单的HTML 个人网页

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>个人网页</title> <style> body { f…...

【SpringCloud微服务实战05】Feign 远程调用

Feign是一个由Netflix开发的轻量级RESTful HTTP服务客户端,用于简化和优雅地调用HTTP API。它允许用户通过Java接口注解来发起请求,而不必像传统方式那样手动构建HTTP请求报文。Feign支持Spring Cloud解决方案,使得服务消费者能够像调用本地接口方法一样调用远程服务。使得开…...

LiveGBS流媒体服务器中海康摄像头GB28181公网语音对讲、语音喊话的配置

LiveGBS海康摄像头国标语音对讲大华摄像头国标语音对讲GB28181语音对讲需要的设备及服务准备 1、背景2、准备2.1、服务端必备条件&#xff08;注意&#xff09;2.2、准备语音对讲设备2.2.1、不支持跨网对讲示例2.2.2、 支持跨网对讲示例 3、开启音频开始对讲4、搭建GB28181视频…...

【前端】尚硅谷Webpack教程笔记

文章目录 1. 基本使用1.1 功能介绍1.2 开始使用 参考视频:尚硅谷Webpack5入门到原理 课件地址 【前端目录贴】 1. 基本使用 1.1 功能介绍 Webpack 是一个静态资源打包工具。 它会以一个或多个文件作为打包的入口&#xff0c;将我们整个项目所有文件编译组合成一个或多个文件输…...

Java泛型使用及局限

Java泛型的局限和使用经验 泛型的局限 任何基本类型不能作为类型参数 经过类型擦除后&#xff0c;List中包含的实际上还是Object的域&#xff0c;而在Java类型系统中Object和基本类型是两套体系&#xff0c;需要通过“自动装包、拆包机制”来进行交互。 2.任何在运行时需要…...

Sklearn线性回归

Scikit-learn 中的线性回归是一个用于监督学习的算法&#xff0c;它用于拟合数据集中的特征和目标变量之间的线性关系。以下是使用 Scikit-learn 实现线性回归的基本步骤&#xff1a; 1. 导入所需库 首先&#xff0c;你需要导入所需的库和模块。 import numpy as np import …...

APP中互联网公司的必备知识

APP中互联网公司的必备知识 敏捷开发&#xff08;scrum&#xff09;模型角色工作流程 项目上线发布策略发布流程灰度发布 APP发布APP软件包类型APP客户端&#xff08;内部&#xff09;发布平台APP客户端&#xff08;线上&#xff09;发布平台 熟悉APP项目&#xff08;tpshop&am…...

论文翻译 - Visual Adversarial Examples Jailbreak Large Language Models

论文链接&#xff1a;https://arxiv.org/pdf/2306.13213.pdf 项目代码&#xff1a;https://github.com/Unispac/Visual-Adversarial-Examples-Jailbreak-Large-Language-Models Visual Adversarial Examples Jailbreak Aligned Large Language Models Abstract1 Introduction2 …...

android so载入过程

源自android 9 看源代码的网页 /bionic/libdl/libdl_static.c 好像没用。都是空的 /bionic/libdl/libdl.cpp 主角 22// These functions are exported by the loader 23// TODO(dimitry): replace these with reference to libc.so101// Proxy calls to bionic loader 102_…...

FlowerShop花店管理系统wpf+sqlserver

FlowerShop花店管理系统wpfsqlserver说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于C#wpf架构和sql server数据库 功能模块&#xff1a; 顾客登录后可以查询花卉详情然后购买 店主登录管理后台 顾客管理 删除顾客多行删…...

如何在群晖NAS部署WPS容器并实现无公网IP远程访问本地office软件

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本&#xff0c;通过…...

【C语言程序设计】C语言求圆周率π(三种方法)

题目一&#xff1a; 利用公式①计求π的近似值&#xff0c;要求累加到最后一项小于10^(-6)为止。 程序代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <math.h> int main(){float s1;float pi0;float i1.0;float n1.0;while(fabs(i)&…...

常见的特殊端口号及其用途

21端口&#xff1a;FTP&#xff08;文件传输协议&#xff09;服务端口。FTP允许用户进行文件传输&#xff0c;如上传和下载文件。22端口&#xff1a;SSH&#xff08;安全外壳协议&#xff09;服务端口。SSH用于远程登录到服务器&#xff0c;并提供加密的数据传输。23端口&#…...

Linux(ubuntu) 安装kotlin

Kotlin 是一种基于 Java 语言的静态类型编程语言&#xff0c;它可以运行于 JVM 上 1. 安装 Java Development Kit (JDK) Kotlin 运行于 JVM 上&#xff0c;所以首先需要安装 Java Development Kit&#xff08;JDK&#xff09; Ubuntu 或 Debian 系统 sudo apt update sudo a…...

微信小程序提交成功设置提示

在微信小程序中&#xff0c;当用户成功提交表单或完成某项操作后&#xff0c;通常我们会设置一个提示来告知用户操作已完成。这种提示通常可以通过几种方式来实现&#xff0c;例如使用 wx.showToast 方法显示一个短暂的提示消息&#xff0c;或者跳转到一个新的页面并显示成功信…...

Pycharm与Anaconda安装

网址&#xff1a; Pycharm&#xff1a;https://www.jetbrains.com/pycharm/ Anaconda&#xff1a;https://www.anaconda.com/download/ 官网下载速度太慢可以选择到清华源下载&#xff1a;https://repo.anaconda.com/archive/ 一&#xff1a;Anaconda安装 安装&#xff1a; …...

阿里云数据盘挂载目录

1、先登录服务器创建新目录aaa 2、云盘都快照备份下。后续操作完核实无误了&#xff0c;您根据您需求删除快照就行&#xff0c; 然后登录服务器内执行&#xff1a; fdisk -l lsblk blkid ll /aaa 3、执行&#xff1a;&#xff08;以下命令是进行数据盘做ext4文件系统并挂载到…...

【Python】探索PyPinyin 库:Python 中的中文拼音转换工具

花未全开月未圆&#xff0c; 半山微醉尽余欢。 何须多虑盈亏事&#xff0c; 终是小满胜万全。 —— 《对抗路—吕布》 PyPinyin 是一个功能强大的 Python 库&#xff0c;用于将中文文本转换为拼音。它提供了丰富的功能&#xff0c;能够满足各种中文文本处理的需求。在本文中&am…...

Linux运维总结:Centos7.6之OpenSSH7.4升级版本至9.3

一、环境信息 操作系统&#xff1a;Centos7.6.1810 OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 注意&#xff1a;升级后由于加密算法的区别&#xff0c;低版本的SSH工具可能无法连接&#xff0c;建议改用Xshell7或SecureCRT9.0以上版本。 二、注意事项 1、 检查防火墙或selinux是否…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

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

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

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...