算法: 二分查找题目练习
文章目录
- 二分查找
- 二分查找
- 在排序数组中查找元素的第一个和最后一个位置
- 搜索插入位置
- x 的平方根
- 山脉数组的峰顶索引
- 寻找峰值
- 寻找旋转排序数组中的最小值
- 点名
- 总结
- 模版
二分查找
二分查找

没啥可说的,轻轻松松~
class Solution {public int search(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left <= right) {int mid = (right + left) / 2;if (nums[mid] > target) {right = mid - 1;} else if (nums[mid] < target) {left = mid + 1;} else {return mid;}}return -1;}
}
在排序数组中查找元素的第一个和最后一个位置

可以使用二分查找.
查找左端点:
- 把区间划分成两个部分, 1. num[mid] < t , num[mid] >= t .
把区间划分成 num[mid] < t 和 num[mid] > t ,这谁都懂,就不说了.
关键是 “=” 给谁? 左边还是右边?
关于为啥给右边,这里就不说了.
我在这里只是讲一个记忆方法(左右都适用):
求左端点,只看左括号,哪个括号在中间,“=” 就给谁.
具体如下:
- 划分好区间,接下来就要想指针的移动方式了.

查找右端点:
-
把区间划分成两个部分, 1. num[mid] <= t , num[mid] > t .
“=” 给谁,参考上面的记忆方法.- 求右端点,只看右括号,哪个括号在中间,“=” 就给谁.
-
指针的移动方式,跟查找左端点的方法类似,自己写写试试~
class Solution {public int[] searchRange(int[] nums, int target) {int[] ret = {-1, -1};if (nums.length == 0)return ret;int left = 0;int right = nums.length - 1;int mid = 0;while (left < right) {mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else {right = mid;}}if (nums[left] == target)ret[0] = left;elsereturn ret;right = nums.length - 1;while (left < right) {mid = left + (right - left + 1) / 2;if (nums[mid] <= target) {left = mid;} else {right = mid - 1;}}ret[1] = left;return ret;}}
坑:
- nums 数组的长度可能为0.
- 二分没写好,容易死循环.
我在写完以后,有个疑问:
- 为啥循环结束后 mid 指向的值,不是我们想要的?
确实困惑了我一会,不过后来一想就明白了,因为出循环后 mid 差一次更新 ( left 或 right已经变了,但是 mid 没有变).
搜索插入位置

用查找左端点的方法,秒了~
坑:
- 注意边界情况
nums[nums.length-1] < target.
class Solution {public int searchInsert(int[] nums, int target) {if(nums[nums.length-1] < target) return nums.length;int left=0,right=nums.length-1;while(left < right) {int mid = left+(right-left)/2;if(nums[mid] < target) {left = mid + 1;} else if(nums[mid] >= target){right = mid;}}return right;}
}
用左端点做完以后,我想了想,为啥不能用右端点做呢?
确实困扰了我一会,后来明白了,题目要查找的值是要 >= target 的.
而使用查找右端点的方法,会漏掉 > target 的情况:

x 的平方根

分析一下,可以把区间划分成 mid*mid <= x 和 mid*mid > x.一看就是右端点,秒了~
坑:
- 数值过大,要用 long 类型.
class Solution {public int mySqrt(int x) {long left = 0, right = x;while (left < right) {long mid = left + (right - left + 1) / 2;if (mid * mid <= x) {left = mid;} else {right = mid - 1;}}return (int) left;}
}
山脉数组的峰顶索引

没想到怎么把数组划分成两部分.
也就是 if(...) 中的条件不会写.
看了看题解,没想到还能这样做.
以 arr[mid - 1] < arr[mid] 划分~
class Solution {public int peakIndexInMountainArray(int[] arr) {int left = 0, right = arr.length - 1;while (left < right) {int mid = left + (right - left + 1) / 2;if (arr[mid - 1] < arr[mid]) {left = mid;} else {// 前面括号内有 +1 ,这里就 -1 .right = mid - 1;}}return left;}
}
寻找峰值

画图不能偷懒,要老老实实的画,写全了~
public int findPeakElement(int[] nums) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] < nums[mid + 1]) {left = mid + 1;} else {right = mid;}}return left;}
寻找旋转排序数组中的最小值

没想出来,题解是用 n-1 这个位置的数来划分区间的.

public int findMin(int[] nums) {int left = 0;int right = nums.length - 1;while (left < right) {int mid = left + (right - left) / 2;if (nums[mid] < nums[nums.length - 1]) {right = mid;} else {left = mid + 1;}}return nums[right];}
下面这个是用 0 位置来划分区间的(需要考虑一个特殊情况~).
public int findMin(int[] nums) {int left = 0;int right = nums.length - 1;if (nums[0] < nums[nums.length - 1]) {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[right];}
点名

写出来了,用的二分~
class Solution {public int takeAttendance(int[] records) {int left = 0;int right = records.length-1;while(left < right) {int mid = left + (right-left+1)/2;if(records[mid] > mid) {right = mid -1;}else if(records[mid] == mid){left = mid;}}return right==records[right]?right+1:right;}
}
总结
- 当有 二段性 时,就可以用二分查找,不必有序~
二段性: 通过某个条件,可以把数组分成两部分,根据题意可以舍弃一部分,这就叫二段性.
模版

本文到这里就结束啦~

相关文章:
算法: 二分查找题目练习
文章目录 二分查找二分查找在排序数组中查找元素的第一个和最后一个位置搜索插入位置x 的平方根山脉数组的峰顶索引寻找峰值寻找旋转排序数组中的最小值点名 总结模版 二分查找 二分查找 没啥可说的,轻轻松松~ class Solution {public int search(int[] nums, int target) {i…...
Qt开发技巧(十三)QList插入操作,扩展类型的使用,关于QSS的坑,Qt的延时方法,Qt编译的三种版本,环境搭建多练练,指向Qt源码的报错
继续讲一些Qt开发中的技巧操作: 1.QList插入操作 关于QList队列的处理中,我们最常用的就是调用append函数添加item,往前插入item很多人第一印象就是调用insert(0,xxx)来插入,其实QList完全提供了往前追加item的函数prepend()、pus…...
docker快速上手
一个轻量的虚拟机,让程序员不再纠结于环境部署,更多集中于代码编写,基础建设,开发 作用: 打包:把你软件运行所需的所有东西打包到一起 分发:把你打包好的“安装包”上传到一个镜像仓库&#…...
JAVA学习-练习试用Java实现“反转链表 II”
问题: 给定单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 示例 1: 输入:head [1,2,3,4,5], left 2, right 4 输出…...
15分钟学 Python 第35天 :Python 爬虫入门(一)
Day 35 : Python 爬虫简介 1.1 什么是爬虫? 网页爬虫(Web Crawler)是自动访问互联网并提取所需信息的程序。爬虫的主要功能是模拟用户通过浏览器访问网页的操作,从而实现对网页内容的批量访问与信息提取。它们广泛应用于数据收集…...
【Qt】Qt学习笔记(一):Qt界面初识
Qt 是一个跨平台应用程序和 UI 开发框架。使用 Qt 您只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序。Qt Creator是跨平台的Qt集成开发环境。 创建项目 Qt的一些界面,初学时一般选择Qt Widgets …...
Unity3D游戏的内存控制详解
前言 Unity3D是一款流行的游戏引擎,支持多种平台,包括PC、移动设备和VR等。随着游戏的复杂性不断提高,Unity3D的内存管理变得尤为重要。本文将详细介绍Unity3D游戏中的内存控制技术,包括自动内存管理、对象池、延迟加载资源和手动…...
《数据结构》--栈【概念应用、图文并茂】
本节讲完栈下次再讲一下队列,最后补充一个串,我们的线性结构基本就完事了。下图中黄色框框圈中的是我们今日份内容(分为两篇博客): 知识体系图 栈(Stack-LIFO)结构 栈的基础概念 栈(Stack)是一个后进先出(Last-In-First-Out)的一个特殊数据…...
国外电商系统开发-运维系统文件下载
文件下载,作者设计的比较先进,如果下载顺利,真的还需要点两次鼠标,所有的远程文件就自动的下载到了您的PC电脑上了。 现在,请您首选选择要在哪些服务器上下载文件: 选择好了服务器以后,现在选择…...
【CSS in Depth 2 精译_045】7.1 CSS 响应式设计中的移动端优先设计原则(上)
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对…...
在线教育新篇章:SpringBoot系统开发策略
2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…...
cmdsh
#!/bin/bash #set -x bindirname "$0" bincd "$bin"; pwd echo $bin if [ $# -lt 2 ] then echo “Usage: ./runRemoteCmd.sh Command MachineTag” echo “Usage: ./runRemoteCmd.sh Command MachineTag confFile” exit fi cmd$1 tag$2 if [ a’ 3 ′…...
一键生成PPT的AI工具-Kimi!
一键生成PPT的AI工具-Kimi! 前言介绍Kimi为什么选择Kimi如何使用Kimi在线编辑PPT下载生成的PPT自己编辑 结语 😀大家好!我是向阳🌞,一个想成为优秀全栈开发工程师的有志青年! 📔今天不来讨论前后…...
java.lang.NoClassDefFoundError: kotlin/Result解决方案
问题 在控制窗口上虽然报错是找不到对应的class,但是呢在我们导入kotlin的后,还是报相同的异常,在网上查找了各种资料,都没有解决方案。 问题分析 在idea2021之后,kotlin都使用远程仓库(kotlinx-coeouti…...
LSTM的变体
一、GRU 1、什么是GRU 门控循环单元(GRU)是一种循环神经网络(RNN)的变体,它通过引入门控机制来控制信息的流动,从而有效地解决了传统RNN中的梯度消失问题。GRU由Cho等人在2014年提出,它简化了…...
LeetCode讲解篇之852. 山脉数组的峰顶索引
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们可以采用二分查找,每次查询区间中点元素与中点下一个元素比较 如果中点元素大于其下一个元素,则表示从中点开始向右是递减趋势,那峰值索引一定小于等于中点,我…...
矿井人员数据集,用于目标检测,深度学习,采用txt打标签,即yolo格式,也有原文件可以自己转换。总共3500张图片的数据量,划分给训练集2446张,
矿井人员数据集,用于目标检测,深度学习,采用txt打标签,即yolo格式,也有原文件可以自己转换。总共3500张图片的数据量,划分给训练集2446张: ### 矿井人员数据集用于目标检测的详细说明 #### 1. …...
消息队列RabbitMQ
文章目录 1. 简介与安装2. 基本概念3. SpringAMQP4. 交换机类型5. 消息转换器5.1 默认转换器5.2 配置JSON转换器 6 生产者的可靠性6.1 生产者超时重连机制6.2 生产者确认机制 6. MQ的可靠性6.1 数据持久化6.2 惰性队列 Lazy Queue 7. 消费者的可靠性7.1 消费者确认机制7.2 失败…...
RabbitMQ概述
什么是MQ MQ (message queue)消息队列 MQ从字⾯意思上看,本质是个队列,FIFO先⼊先出,只不过队列中存放的内容是消息(message).消息可以⾮常简单,⽐如只包含⽂本字符串,JSON等,也可以很复杂,⽐如内嵌对象 RabbitMQ是MQ的一种实现,是Rabbit 企业下的⼀个消息队列产…...
Golang学习路线
以下是一条学习Golang(Go语言)的路线: 一、基础入门 1. 环境搭建 安装Go编译器,在官网(https://golang.org/dl/)下载适合操作系统的安装包并配置好环境变量。 2. 语法学习学习变量、数据类型(…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
