【LeetCode Hot100 双指针】移动零、盛最多水的容器、三数之和、接雨水
双指针
- 1. 移动零
- 题目描述
- 解题思路
- 关键思路:
- 步骤:
- 时间复杂度:
- 空间复杂度:
- 代码实现
- 2. 盛最多水的容器
- 题目解析
- 解题思路
- 代码实现
- 3. 三数之和
- 问题描述:
- 解题思路:
- 算法步骤:
- 代码实现:
- 4. 接雨水
- 问题描述:
- 解题思路:
- 算法步骤:
- 代码实现:
1. 移动零
题目描述
给定一个数组 nums
,编写一个方法,将所有零元素移动到数组的末尾,同时保持非零元素的相对顺序不变。必须 原地 修改数组,且不能使用额外的数组。
解题思路
此问题要求将数组中的所有零元素移动到末尾,保持非零元素的相对顺序不变,并且必须在原数组上修改。常规的做法可能会用两个临时数组,但这里需要在 O(1) 空间复杂度下完成任务。因此,我们需要设计一个在原数组上操作的解法。
关键思路:
我们可以使用 双指针法 来解决该问题:
- 指针
p
: 用于遍历数组中的元素,用来指向需要替换的位置(即当前非零元素应该放的位置)。 - 指针
q
: 用于遍历数组中的元素,指向当前正在检查的元素。
步骤:
-
初始化两个指针
p
和q
:p
指向当前可以插入非零元素的位置。q
用来遍历整个数组,检查每一个元素。
-
遍历数组:
- 当
nums[p]
为零时:- 如果
nums[q]
也为零,直接跳过q
,继续检查下一个元素。 - 如果
nums[q]
为非零元素,交换nums[p]
和nums[q]
,将非零元素移到前面,同时将p
和q
向后移动。
- 如果
- 当
nums[p]
不是零时,直接将p
向后移动,继续检查下一个位置。
- 当
-
结束条件: 当
q
遍历完数组时,操作结束。
时间复杂度:
- 单遍历数组,时间复杂度为 O(n),其中
n
是数组的长度。
空间复杂度:
- 使用了常数空间,仅使用了两个指针,空间复杂度为 O(1)。
代码实现
class Solution {public void moveZeroes(int[] nums) {int p = 0, q = 1;while (q < nums.length) {if (nums[p] == 0) {while (q < nums.length - 1 && nums[q] == 0) {q++;}nums[p] = nums[q];nums[q] = 0;} p++;q++;}}
}
2. 盛最多水的容器
题目解析
题目要求我们在一个给定的整数数组 height[]
中,找到两条垂直线所构成的容器的最大面积。两条线的 x 轴坐标为数组中的两个元素位置,而容器的高度则是由这两个位置的较短的线决定的。
我们可以利用 双指针法 来解决这个问题,这样可以在一次遍历中找到最大面积,且时间复杂度为 O(n)。
解题思路
-
定义两个指针:
- 初始化两个指针
p
和q
,分别指向数组的两端。即p = 0
,q = height.length - 1
。
- 初始化两个指针
-
计算面积:
- 在每一步中,我们计算当前两条垂直线之间的面积,面积的计算公式为:
area = ( q − p ) × min ( height[p] , height[q] ) \text{area} = (\text{q} - \text{p}) \times \min(\text{height[p]}, \text{height[q]}) area=(q−p)×min(height[p],height[q]) q - p
是两条线之间的宽度,min(height[p], height[q])
是这两条线所能组成的容器的高度。
- 在每一步中,我们计算当前两条垂直线之间的面积,面积的计算公式为:
-
移动指针:
- 为了找到可能的最大面积,我们需要移动其中较短的线来尝试提高容器的高度。我们移动短板的指针,若
height[p] < height[q]
,则p++
;否则,q--
。通过这种方式,我们不断调整指针,寻找可能的最大面积。
- 为了找到可能的最大面积,我们需要移动其中较短的线来尝试提高容器的高度。我们移动短板的指针,若
-
结束条件:
- 当
p
与q
相遇时,所有可能的组合都已经检查过,我们返回最大面积。
- 当
-
为什么移动短板
- 面积是由短板来决定的,如果选择移动长板保留短板,那么移动后的面积不可能比移动前的更大了。 假设移动长板后得到的新板长度比之前的短板长,那么容器的高度仍然是短板的长度,而宽度减小了;如果移动长板后得到的新板长度比之前的短板短,那么面积就更小了。
代码实现
class Solution {public int maxArea(int[] height) {int p = 0, q = height.length - 1; // 初始化指针int result = 0; // 用来存储最大面积while (p < q) {int area = (q - p) * Math.min(height[p], height[q]); // 计算当前的面积result = Math.max(result, area); // 更新最大面积// 移动短板if (height[p] < height[q]) {p++; // 如果左边的高度小,移动左指针} else {q--; // 如果右边的高度小,移动右指针}}return result; // 返回最大面积}
}
3. 三数之和
问题描述:
给定一个整数数组 nums
,找出所有和为零的三元组,要求不重复地返回结果。
解题思路:
这个问题要求在数组中找到所有和为零的三元组,并且不允许返回重复的三元组。考虑到以下几点:
- 排序:首先,我们可以将数组
nums
进行排序,这样可以更方便地处理重复元素并使用双指针方法进行优化。 - 去重:由于数组可能包含重复的元素,我们需要跳过重复的三元组。可以通过跳过相同的元素来避免重复结果。
- 双指针:对于每个固定的
i
,我们使用双指针j
和k
来遍历剩余的数组,寻找和为零的元素。这样可以有效地减少时间复杂度。 - 优化:通过判断最小的三个数和最大的两个数的和的情况,提前排除无解的情况,减少不必要的计算。
算法步骤:
- 排序数组:对
nums
数组进行排序。 - 遍历数组:用一个
i
来遍历数组,确保nums[i]
是固定的。 - 使用双指针:对于每一个固定的
i
,使用两个指针j
和k
来遍历数组中的元素,查找nums[i] + nums[j] + nums[k] == 0
的三元组。 - 跳过重复元素:跳过重复的元素,以避免返回重复的三元组。
- 优化判断:通过判断数组中最小和最大的元素的和来减少不必要的计算。
代码实现:
class Solution {public List<List<Integer>> threeSum(int[] nums) {// 先把数组变成有序的数组Arrays.sort(nums);List<List<Integer>> ans = new ArrayList<>();int n = nums.length;// 最后留两个位置给 j 和 kfor (int i = 0; i < n - 2; i++) {if (i > 0 && nums[i] == nums[i - 1]) {// 如果和上一个数值相同就跳过,避免重复continue;}int j = i + 1;int k = n - 1;// 优化 1: 最小的三个数加和 > 0 就说明没有 j, k 加一起能 = 0,都 > 0if (nums[i] + nums[i + 1] + nums[i + 2] > 0) break;// 优化 2:nums[i] 和两个最大的数相加都 < 0,说明当前 i 和后面的任意 j, k 相加都 < 0if (nums[i] + nums[n - 1] + nums[n - 2] < 0) continue;while (j < k) {int s = nums[i] + nums[j] + nums[k];if (s == 0) {List<Integer> list = new ArrayList<>();list.add(nums[i]);list.add(nums[j]);list.add(nums[k]);ans.add(list);j++;// 避免重复while (j < k && nums[j] == nums[j - 1]) {j++;}k--;// 避免重复while (k > j && nums[k] == nums[k + 1]) {k--;}} else if (s > 0) {k--;} else {j++;}}}return ans;}
}
4. 接雨水
问题描述:
给定一个整数数组 height
,其中每个元素代表一个柱子的高度。请计算能够接住多少个雨水。
解题思路:
此问题是经典的“接雨水”问题。我们需要计算每个位置能接住的雨水量。对于每个位置,能接住的雨水量取决于该位置的左边和右边的最大高度。因此,我们可以将问题转化为以下步骤:
- 计算每个位置的左边最大高度:对于数组中的每个位置
i
,我们可以记录从左到右遍历时,当前位置左边的最大高度。这样可以确定该位置上方能够容纳多少水。 - 计算每个位置的右边最大高度:对于数组中的每个位置
i
,我们可以记录从右到左遍历时,当前位置右边的最大高度。同样,这也帮助我们计算该位置上方能容纳多少水。 - 计算每个位置的水量:每个位置的水量由当前高度、左边最大高度和右边最大高度共同决定。具体来说,当前位置能容纳的水量为:
Math.min(left_max, right_max) - height[i]
。
算法步骤:
- 创建两个数组
pre_max
和suf_max
:分别记录每个位置的左边最大高度和右边最大高度。 - 计算左边最大高度:从左到右遍历,更新
pre_max[i]
为当前位置i
及其左边所有位置的最大高度。 - 计算右边最大高度:从右到左遍历,更新
suf_max[i]
为当前位置i
及其右边所有位置的最大高度。 - 计算接住的雨水:对于每个位置
i
,水量为Math.min(pre_max[i], suf_max[i]) - height[i]
,然后将水量累加得到总水量。
代码实现:
class Solution {public int trap(int[] height) {int ans = 0;int n = height.length;int[] pre_max = new int[n];int[] suf_max = new int[n];// 计算左边最大高度pre_max[0] = height[0];for (int i = 1; i < n; i++) {pre_max[i] = Math.max(pre_max[i-1], height[i]);}// 计算右边最大高度suf_max[n-1] = height[n-1];for (int i = n-2; i >= 0; i--) {suf_max[i] = Math.max(suf_max[i+1], height[i]);}// 计算每个位置的水量for (int i = 0; i < n; i++) {ans += Math.min(pre_max[i], suf_max[i]) - height[i];}return ans;}
}
相关文章:

【LeetCode Hot100 双指针】移动零、盛最多水的容器、三数之和、接雨水
双指针 1. 移动零题目描述解题思路关键思路:步骤:时间复杂度:空间复杂度: 代码实现 2. 盛最多水的容器题目解析解题思路代码实现 3. 三数之和问题描述:解题思路:算法步骤:代码实现: …...

HTML应用指南:利用POST请求获取接入比亚迪业态的充电桩位置信息
在新能源汽车快速发展的今天,充电桩的分布和可用性成为了影响用户体验的关键因素之一。比亚迪作为全球领先的新能源汽车制造商,不仅在车辆制造方面取得了卓越成就,也在充电基础设施建设上投入了大量资源。为了帮助用户更方便地找到比亚迪充电桩的位置,本篇文章,我们将探究…...

Android车机DIY开发之软件篇(十二) AOSP12下载编译
Android车机DIY开发之软件篇(十二) AOSP12下载编译 sudo apt-get update sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib gmultilib libc6-dev-i386 lib32ncurses5-dev libx11-dev lib32z-dev ccache libgl1-mesa-…...

Jenkins+gitee 搭建自动化部署
Jenkinsgitee 搭建自动化部署 环境说明: 软件版本备注CentOS8.5.2111JDK1.8.0_211Maven3.8.8git2.27.0Jenkins2.319最好选稳定版本,不然安装插件有点麻烦 一、安装Jenkins程序 1、到官网下载相应的版本war或者直接使用yum安装 Jenkins官网下载 直接…...

【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案
企业的应用场景 数据清洗:在进行数据导入或分析之前,往往需要对大量文本数据进行预处理,比如去除文本中的无关字符(中文、英文),只保留需要的联系信息(手机号码、固话号码、邮箱)。…...

Linux系统引导与服务管理
目录 一、Linux引导过程 1、引导过程概述 1.1、BIOS开机自检 1.2、MBR读取 1.3、加载引导加载程序(GRUB) 1.4、内核加载 1.5、初始化进程(init) 二、服务 2.1、服务类型 2.2、服务管理工具 三、运行级别 四、systemd …...

网络工程师 (30)以太网技术
一、起源与发展 以太网技术起源于20世纪70年代,最初由Xerox公司的帕洛阿尔托研究中心(PARC)开发。最初的以太网采用同轴电缆作为传输介质,数据传输速率为2.94Mbps(后发展为10Mbps),主要用于解决…...

react项目引入tailwindcss不生效解决方案
根据tailwindcss官网的操作步骤下来,样式未生效,且未报错,看了挺多的资料,还是并未解决。 后面在另一个项目尝试时,报了下面的问题: Error: PostCSS plugin tailwindcss requires PostCSS 8 根据这个链接…...

【C#】条件运算符
1.逻辑与(&&) Console.WriteLine(true && true);//true Console.WriteLine(true && false);//false Console.WriteLine(false && false);//false2.逻辑或(||) Console.WriteLine(true || true);//true Console.WriteLine(true || false);//t…...

Windows11+PyCharm利用MMSegmentation训练自己的数据集保姆级教程
系统版本:Windows 11 依赖环境:Anaconda3 运行软件:PyCharm 一.环境配置 通过Anaconda Prompt(anaconda)打开终端创建一个虚拟环境 conda create --name mmseg python3.93.激活虚拟环境 conda activate mmseg 4.安装pytorch和cuda tor…...

WPS计算机二级•文档的文本样式与编号
听说这是目录哦 标题级别❤️新建文本样式 快速套用格式🩷设置标题样式 自定义设置多级编号🧡使用自动编号💛取消自动编号💚设置 页面边框💙添加水印🩵排版技巧怎么分栏💜添加空白下划线&#x…...

Word中Ctrl+V粘贴报错问题
Word中CtrlV粘贴时显示“文件未找到:MathPage.WLL”的问题 Word的功能栏中有MathType,但无法使用,显示灰色。 解决方法如下: 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件,分别复…...

python-leetcode 24.回文链表
题目: 给定单链表的头节点head,判断该链表是否为回文链表,如果是,返回True,否则,返回False 输入:head[1,2,2,1] 输出:true 方法一:将值复制到数组中后用双指针法 有两种常用的列表实现&#…...

数据治理双证通关经验分享 | CDGA/CDGP备考全指南
历经1个月多的系统准备,本人于2024年顺利通过DAMA China的CDGA(数据治理工程师)和CDGP(数据治理专家)双认证。现将备考经验与资源体系化整理,助力从业者高效通关。 🌟 认证价值与政策背景 根据…...

3.4 学习UVM中的uvm_monitor类分为几步?
文章目录 前言1. 定义2. 核心功能3. 适用场景4. 使用方法5. 完整代码示例5.1 事务类定义5.2 Monitor 类定义5.3 Scoreboard 类定义5.4 测试平台 6. 代码说明7. 总结 前言 以下是关于 UVM 中 uvm_monitor 的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例&…...

Java在大数据处理中的应用:从MapReduce到Spark
Java在大数据处理中的应用:从MapReduce到Spark 大数据时代的到来让数据的存储、处理和分析变得前所未有的重要。随着数据量的剧增,传统的单机计算方式已经无法满足处理需求。为了解决这个问题,许多分布式计算框架应运而生,其中Ma…...

日常吐槽。
一、写在前面 stereopy日常出bug(github issue里得有一半的问题是我提的,当然也有可能是因为我菜),stereopy自己生成的anndata自己不能计算空间共现关系,还是靠squidpy才能计算。另外还要一些函数一开并行计算就报错,这里留一些s…...

2025最新版Node.js下载安装~保姆级教程
1. node中文官网地址:http://nodejs.cn/download/ 2.打开node官网下载压缩包: 根据操作系统不同选择不同版本(win7系统建议安装v12.x) 我这里选择最新版win 64位 3.安装node ①点击对话框中的“Next”,勾选同意后点…...
机器学习:学习记录(二)
1. 机器学习中的常用函数 logistic函数(sigmoid函数):非线性激活函数,将R区间映射到(0,1)区间 ReLU函数:非线性激活函数,简单可以写作max(0,x),在0处不可导,但是可以人为定义其导数…...

迁移学习 Transfer Learning
迁移学习(Transfer Learning)是什么? 迁移学习是一种机器学习方法,它的核心思想是利用已有模型的知识来帮助新的任务或数据集进行学习,从而减少训练数据的需求、加快训练速度,并提升模型性能。 …...

实现:多活的基础中间件
APIRouter : 路由分发服务 API Router 是一个 HTTP 反向代理和负载均衡器,部署在公有云中作为 HTTP API 流量的入口,它能识别 出流量的归属 shard ,并根据 shard 将流量转发到对应的 ezone 。 API Router 支持多种路由键&am…...

Mybatis源码01 - 总体框架设计
Mybatis总体框架设计 文章目录 Mybatis总体框架设计一:MyBatis架构概览1:接口层1.1:使用传统的MyBatis提供的API1.2:使用Mapper接口 2:数据处理层【核心】2.1:参数映射和动态SQL语句生成2.2:SQL…...

在大型语言模型(LLM)框架内Transformer架构与混合专家(MoE)策略的概念整合
文章目录 传统的神经网络框架存在的问题一. Transformer架构综述1.1 transformer的输入1.1.1 词向量1.1.2 位置编码(Positional Encoding)1.1.3 编码器与解码器结构1.1.4 多头自注意力机制 二.Transformer分步详解2.1 传统词向量存在的问题2.2 详解编解码…...

Selenium WebDriver自动化测试(扩展篇)--Jenkins持续集成
文章目录 一、引言二、Jenkins简介三、安装部署Jenkins安装部署 四、集成Git与Maven安装必要的插件配置Git配置Maven 五、创建Job创建自由风格的项目配置源码管理配置构建触发器配置构建环境配置构建步骤配置Post-build Actions 六、触发构建示例:GitHub Webhook触发…...

Wiki文档转换为Word技术
一、技术背景与目标 Wiki系统导出的文档通常以HTML格式存在,且内容分散在多个文件中,每个页面对应一个HTML文件。然而,Microsoft Word(Word)在处理HTML文件时,仅支持单个HTML文件的导入。因此,为了将Wiki导出的内容转换为Word可识别的格式,必须将分散的HTML文件整合为一…...

1.【线性代数】——方程组的几何解释
一 方程组的几何解释 概述举例举例一1. matrix2.row picture3.column picture 概述 三种表示方法 matrixrow picturecolumn picture 举例 举例一 { 2 x − y 0 − x 2 y 3 \begin{cases} 2x - y 0 \\ -x 2y 3 \end{cases} {2x−y0−x2y3 1. matrix [ 2 − 1 − 1 …...

力扣1448. 统计二叉树中好节点的数目
Problem: 1448. 统计二叉树中好节点的数目 文章目录 题目描述思路复杂度Code 题目描述 思路 对二叉树进行先序遍历,边遍历边对比并更新当前路径上的最大值pathMax,若当pathMax小于等于当前节点值,则好节点的数目加一 复杂度 时间复杂度: O (…...

【C#零基础从入门到精通】(二)——C#注释和命名法详解
【C#零基础从入门到精通】(二)——C#注释和命名法详解 C# 中的注释 定义 在 C# 里,注释是一种特殊的代码文本,它不会被编译器执行,主要用于对代码进行解释、说明,帮助开发者更好地理解代码的功能、用途、实现思路以及注意事项等,提升代码的可读性和可维护性。 注释类型…...

SQLServer的创建,表创建,主键,约束,模糊查询
设置 注意: 设置完成之后 重新启动 创建数据库 注意: 这个目标路径必须要有该文件名的文件夹 -- 指向 master 数据库,告诉它我们要创建一个新的数据库操作了 use master go-- 创建数据库 create database StudentManageDB on primary (-- 以下四个组成部分缺一不可…...

DeepSeek深度思考:客户端(Android/iOS)架构设计指南
目标读者:中高级开发者、架构师 适用场景:大型复杂应用开发、跨团队协作、长期维护迭代 一、架构设计核心原则 1.模块化(Modularization) 横向拆分:按功能边界划分(如登录、支付、消息模块)纵向…...