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

二分查找1

1. 二分查找(704)

题目描述:
在这里插入图片描述
算法原理:
暴力解法就是遍历数组来找到相应的元素,使用二分查找的解法就是每次在数组中选定一个元素来将数组划分为两部分,然后因为数组有序,所以通过大小关系舍弃一部分数组,最终不断重复这个过程完成查找,时间复杂度可以达到logN。
代码如下:

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

题目链接

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

题目描述:
在这里插入图片描述
朴素二分查找:
这题我们可以先使用朴素二分查找的方法取找到等于target的元素下标,此时再分别使用两个循环去比较左右两边元素是否与target相等,如果相等则分别向左和向右移动,最终返回对应的下标即可,这个过程很好理解。
代码如下:

class Solution {public int[] searchRange(int[] nums, int target) {int left = 0, right = nums.length - 1;int index1 = -1, index2 = -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 {index1 = mid;index2 = mid;while (index1 - 1 >= 0 && nums[index1] == nums[index1 - 1]) {index1--;}while (index2 + 1 < nums.length && nums[index2] == nums[index2 + 1]) {index2++;}break;}}return new int[] { index1, index2 };}
}

优化朴素二分查找:
首先我们去寻找target的左边界,为了便于理解我们给出图1,数组的元素可以分为两个部分,前半部分是小于target的元素,后一部分是大于等于target的部分。
图1
在这里插入图片描述
如图2,当我们的nums[mid]也就是x落入前半部分的时候,为了去接近target需要使得left=mid+1,当我们的x落入后半部分的时候,此时我们不能够使right=mid-1,因为如果说此时x是等于target的并且是左边的最后一个target,那么将right-1后面就直接再也找不到正确的target了。综上,如果x落入图1的第二段区间,那么就使得right=mid。很好理解的一点就是通过这样的操作,left在不断的向右移动,right在不断的向左移动但是它的下标也不会超出图1第二段区间的左边,这样我们就能够找到连续target的左边界。
图2
在这里插入图片描述
然后我们来处理两个细节问题,第一个问题就是这样使用二分查找,它的循环条件是使用left<right还是left<=right。我们朴素二分查找是使用后者的,但是在这里要使用前者。为什么呢,这里先分三种情况:
(1)target在right和left区间之内
在这种情况下,最终right会等于left,此时跳出循环即可,直接得到的下标就是正确答案,根本不需要去额外在循环当中去分三种情况> < ==。
(2)left和right区间内都是小于target的
此时left不断的加一最终和right相等跳出循环即可,然后判断nums[right]是否等于target。
(3)left和right区间内都是大于target
此时right不断向右最终和left相等跳出循环。
以上是选择left<right的原因之一,另一个原因就是使用left<=right会造成死循环,当我们使用图2中的方法来处理最终得到结果时,此时left等于right,如果使用left<=right下一次不会跳出而是会进入死循环,这一点还是很好理解的。
综上三种情况,我们使用left<right这样的循环条件,是因为当跳出循环时我们可以进行判断nums[right]是否等于target从而直接得到结果,另外可以防止死循环。
第二个细节问题就是中点的选择,一般是有两种方式来计算中点如图3。
图3
在这里插入图片描述
图3中两种计算中点的方式在朴素二分查找中都是可以适用的,但是这里也就是按照图2的计算方式来说两种方式是有差别的,如果我们使用第二种计算方式,如果我们将left和right的区间缩小到两个元素,也就是left+1等于right这种情况,此时mid计算为right,nums[mid]等于target,right=mid,后面的循环mid经过计算又等于原来的值,由此进入死循环,为了避免这种情况我们就需要使用第一种计算中点的方式。
以上就是求连续的target左边界的分析,对于右边界的分析也是类似的,唯一需要注意的就是此时计算中点的方式要选择第二种否则会造成死循环。
优化后代码如下:

class Solution {public int[] searchRange(int[] nums, int target) {int left1 = 0, right1 = nums.length - 1;if (right1 == -1) {return new int[] { -1, -1 };}int[] ret = new int[2];while (left1 < right1) {int mid1 = left1 + (right1 - left1) / 2;if (nums[mid1] < target) {left1 = mid1 + 1;} else {right1 = mid1;}}if (nums[right1] == target) {ret[0] = right1;} else {ret[0] = -1;}int left2 = 0, right2 = nums.length - 1;while (left2 < right2) {int mid2 = left2 + (right2 - left2 + 1) / 2;if (nums[mid2] > target) {right2 = mid2 - 1;} else {left2 = mid2;}}if (nums[left2] == target) {ret[1] = left2;} else {ret[1] = -1;}return ret;}
}

解题模板:
在这里插入图片描述
下面出现减一上面就需要加一。
题目链接

3. 搜索插入位置(35)

题目描述:
在这里插入图片描述
在这里插入图片描述

算法原理:
根据题目知道,这里的数组是一个升序并且无重复元素的数组,并且如果数组内包含target就求出target的下标,如果数组中不包含target就求出第一个大于target的数的下标,这就是题目的要求。那么我们就可以将数组分为两部分,第一部分是小于target的部分,第二个部分是大于等于target的部分,那么我们直接求出第二部分的左边界即可。前面的题目我们也给出了模板以及解题的思路,具体看代码。
代码如下:

class Solution {public int searchInsert(int[] nums, int target) {int left = 0, right = nums.length - 1;if (nums[right] < target) {return right + 1;}while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else {right = mid;}}return right;}
}

题目链接

4. x 的平方根 (69)

题目描述:
在这里插入图片描述

算法原理:
根据题目我们知道可以将1到x就当成数组中的数,然后我们需要去找到一个数n去满足n*n等于x,这个n就可以使用二分查找来进行寻找,将1到x分为两部分,一部分是数的平方小于等于x另一部分是数的平方大于x,显然我们只需要找到第一部分的右边界即可。不过这题提交的时候要注意数据溢出的问题,要确定好数的类型。
代码如下:

class Solution {public int mySqrt(int x) {if (x == 0) {return 0;}int right = x, left = 1;while (left < right) {long mid = left + (right - left + 1) / 2;if (mid * mid <= x) {left = (int) mid;} else {right = (int) mid - 1;}}return left;}
}

题目链接

相关文章:

二分查找1

1. 二分查找&#xff08;704&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 暴力解法就是遍历数组来找到相应的元素&#xff0c;使用二分查找的解法就是每次在数组中选定一个元素来将数组划分为两部分&#xff0c;然后因为数组有序&#xff0c;所以通过大小关系舍弃…...

什么美业门店管理系统好用?2024美业收银系统软件排名分享

美业SAAS系统在美容、美发、美甲等行业中十分重要&#xff0c;这种系统为美业提供了一种数字化解决方案&#xff0c;帮助企业更高效地管理业务和客户关系。 美业门店管理系统通常提供预约管理、客户管理、库存管理、报表生成等一系列功能&#xff0c;以满足美容院、美发沙龙等…...

【文件上传】

文件上传漏洞 FileUpload 0x01 定义 服务端未对客户端上传文件进行严格的 验证和过滤造成可上传任意文件情况&#xff1b;0x02 攻击满足条件&#xff1a; 1. 上传文件能够被Web容器解释执行   2. 找到文件位置   3.上传文件未被改变内容。&#xff08;躲避安全检查&#…...

Golang 单引号、双引号和反引号的概念、用法以及区别

在 Golang&#xff08;Go 语言&#xff09;中&#xff0c;单引号 ()、双引号 (") 和反引号 () 用于不同类型的字符串和字符表示。以下是它们的概念、用法和区别&#xff1a; 1. 单引号 () 概念 单引号用于表示 字符&#xff08;rune 类型&#xff09;。一个字符表示一个…...

linux和mysql基础指令

Linux中nano和vim读可以打开记事文件。 ifdown ens33 ifup ens33 关闭&#xff0c;开启网络 rm -r lesson1 gcc -o code1 code1.c 编译c语言代码 ./code1 执行c语言代码 rm -r dir 删除文件夹 mysql> show databases-> ^C mysql> show databases; -------…...

JDK 为什么需要配置环境变量

前言 首先&#xff0c;我们要知道 Java 程序的执行过程。首先将 xxx.java 文件&#xff08;使用 javac 编译指令&#xff09;编译成 xxx.class 文件&#xff08;字节码文件&#xff09;&#xff0c;再将字节码文件&#xff08;使用 java 执行指令&#xff09;解释成电脑所能认识…...

ViewBinding的使用(因为kotlin-android-extensions插件的淘汰)

书籍&#xff1a; 《第一行代码 Android》第三版 开发环境&#xff1a; Android Studio Jellyfish | 2023.3.1 问题&#xff1a; 3.2.4在Activity中使用Toast章节中使用到了kotlin-android-extensions插件,但是该插件已经淘汰,根据网上了解,目前使用了新的技术VewBinding替…...

IOS Swift 从入门到精通:ios 连接数据库 安装 Firebase 和 Firestore

创建 Firebase 项目 导航到Firebase 控制台并创建一个新项目。为项目指定任意名称。 在这里插入图片描述 下一步,启用 Google Analytics,因为我们稍后会用到它来发送推送通知。 在这里插入图片描述 在下一个屏幕上,选择您的 Google Analytics 帐户(如果已创建)。如果没…...

QT4-QT5(6)-const char* QString 乱码转换

我简单粗暴的给出个结论&#xff1a; QString GBK编码正常&#xff0c;可以转UTF-8编码&#xff0c;但会有少量乱码。 const char* 编码就不要转编码&#xff0c;转哪个都是乱码。 UTF-8.cpp 下 1.QString GBK->UTF-8 2.const char * GBK->UTF-8 const char *…...

报错:RuntimeError_ cuDNN error_ CUDNN_STATUS_EXECUTION_FAILED

原因&#xff1a;pytorch与cuda版本不对 也有可能是内存空间不足&#xff0c;可以更改虚拟空间大小&#xff0c;参考&#xff1a;解决电脑内存不足问题&#xff1a;Win10虚拟内存设置指南...

黑马点评项目总结1-使用Session发送验证码和登录login和 使用Redis存储验证码和Redis的token登录

黑马先是总结了从session实现登录&#xff0c;然后是因为如果使用了集群方式的服务器的话&#xff0c;存在集群共享session互相拷贝效率低下的问题&#xff0c;接着引出了速度更快的内存型的kv数据库Redis&#xff0c; 使用Session发送验证码和登录login 举个例子&#xff1a…...

【大模型】Vllm基础学习

前言&#xff1a;vllm是一个大语言模型高速推理框架&#xff0c;旨在提高大模型的服务效率。优势是内存管理&#xff0c;实现的核心是pageattetion算法。仅在gpu上加速&#xff0c;不在cpu加速。 目录 1. PageAttention2. 实践2.1 安装2.2 离线推理2.3 适配OpenAI的api 1. Page…...

使用vue动态给同一个a标签添加内容 并给a标签设置hover,悬浮文字变色,结果鼠标悬浮有的字上面不变色

如果Vue的虚拟DOM更新机制导致样式更新不及时&#xff0c;你可以尝试以下几种方法来解决这个问题&#xff1a; 确保使用响应式数据&#xff1a; 确保你使用的数据是响应式的&#xff0c;并且任何对这些数据的更改都会触发视图的更新。在Vue中&#xff0c;你应该使用data对象中的…...

【ajax实战06】进行文章发布

本文章目标&#xff1a;收集文章内容&#xff0c;并提交服务器保存 一&#xff1a;基于form-serialize插件收集表单数据 form-serialize插件仅能收集到表单数据&#xff0c;除此之外的数据无法收集到 二&#xff1a;基于axios提交到服务器保存 三&#xff1a;调用alert警告…...

Codeforces Round 954 (Div. 3)(A~E)

目录 A. X Axis B. Matrix Stabilization C. Update Queries D. Mathematical Problem A. X Axis Problem - A - Codeforces 直接找到第二大的数&#xff0c;答案就是这个数与其他两个数的差值的和。 void solve() {vector<ll>a;for (int i 1; i < 3; i){int x;…...

基于Java微信小程序同城家政服务系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…...

[21] Opencv_CUDA应用之使用Haar级联的对象检测

Opencv_CUDA应用之使用Haar级联的对象检测 Haar级联使用矩形特征来检测对象,它使用不同大小的矩形来计算不同的线和边缘特征。矩形包含一些黑色和白色区域,如下图所示,它们在图像的不同位置居中 类Haar特征检测算法的思想是计算矩形内白色像素和黑色像素之间的差异这个方法的…...

CXL:拯救NVMe SSD缓存不足设计难题-2

LMB提出了基于CXL协议的内存扩展框架和内核模块。该方案利用CXL内存扩展器作为物理DRAM源&#xff0c;旨在提供一个统一的内存分配接口&#xff0c;使PCIe和CXL设备都能方便地访问扩展的内存资源。通过这个接口&#xff0c;NVMe驱动和CUDA的统一内存内核驱动可以直接高效地访问…...

Opencv学习项目6——pyzbar

在之前我们学习了解码图片中的二维码&#xff0c;这次我们开启摄像头来解码视频中二维码 开启摄像头 # 打开摄像头 cap cv2.VideoCapture(0) cap.set(3, 640) # 设置摄像头画面宽度 cap.set(4, 480) # 设置摄像头画面高度 我使用的是笔记本上的摄像头来进行的&#xff0c;…...

Switch 刷安卓11 (LineageOS 18.1) 大气层双系统图文教程

很多朋友手上已经拥有了完成硬破的 Switch &#xff0c;但又不甘心仅仅使用 Switch 本身的地平线系统&#xff0c;Switch 刷安卓 (Android 11) 会是一个好的选择&#xff0c;虽然 Switch 的 CPU 性能拉跨&#xff0c;但和桌面平台同一设计思路的TegraX1 GPU 可谓是先于时代&…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...