LeetCode算法题:11. 盛最多水的容器(Java)(双指针问题总结)

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

在这里插入图片描述

提示:

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

解题思路:

定义两个指针啊a,b分别指向height数组的第一个元素和第二个元素,表示容器的左边和容器右边,定义一个maxVolume表示记录的最大容量,初始定义为0。定义两层循环,外层循环a指针,内层循环b指针,如果当a,b指针所形成容器的容量大于maxVolume时更新maxVolume。遍历完之后找到最大值。

class Solution {public int maxArea(int[] height) {int maxVolume = 0;for(int a=0;a<height.length;a++){for(int b=a+1;b<height.length;b++){if(((b-a)*Math.min(height[a],height[b]))>maxVolume)maxVolume = (b-a)*Math.min(height[a],height[b]);}}return maxVolume;}
}

时间复杂度为O(n^2),空间复杂度为O(1)。提交报错:
在这里插入图片描述
时间复杂度过高,得想办法降低时间复杂度。

修改思路:

初始化定义两个指针a,b分别指向height数组第一个元素和最后一个元素。初始化maxVolume等于height[a]*height[b]表示当前最大容量,分析一下可以知道,当前状态的容量底宽是最宽的情况了,那么容量的大小,取决于左边和后边较矮的边。例如如果当前是a,b所指高度是a所指高度较矮,那么要做到下一次找到的容器比原来的大,只能是找到一个更高的左边才有可能。同理,如果是右边更矮,则要找到一个更高的右边才行。因此每次移动较矮的那一边,如果是左边更矮,则向右移,找到一个比原来左边高的边,重新计算容量;如果是右边更矮,则向左移,找到一个比原来右边高的边。重新计算容量,如果比之前容量大,则更新maxVolume。直到左边指针越过右边指针,则停下。当前maxVolume是最大的容量。

代码:

class Solution {public int maxArea(int[] height) {int a=0,b=height.length-1;int maxVolume=(b-a)*(Math.min(height[a],height[b]));int maxLeftEdge = height[a],maxRightEdge = height[b];while(a<b){if(height[a]<height[b]){a = a+1;while(height[a]<=maxLeftEdge&&a<b)a=a+1;}else{b = b-1;while(height[b]<=maxRightEdge&&a<b)b=b-1;}if((b-a)*(Math.min(height[a],height[b]))>maxVolume){maxVolume = (b-a)*(Math.min(height[a],height[b]));maxLeftEdge = height[a];maxRightEdge = height[b];}}return maxVolume;}
}

结果:

在这里插入图片描述

上述算法时间复杂度为O(n),空间复杂度为O(1)。
但是看到时间复杂度依然有改进空间。查看1ms时间复杂度的代码:

class Solution {public int maxArea(int[] height) {int l =0,r =height.length-1;int max =0;while(l<r){if(height[r]>height[l]){max = Math.max(max,(r-l)*height[l]);int tmp = height[l];while(tmp>= height[l]&&l<r) l++;}else{max = Math.max(max,(r-l)*height[r]);int tmp = height[r];while(tmp>= height[r]&&l<r) r--;}}return max;}
}

观察发现,总体代码逻辑与我自己的一样,不同点在于每次的maxVolume计算使用了Math.max(max,(r-l)*height[l]),同时是放在if语句中计算。同时只是使用一个临时变量存储之前左右边高度。避免了重复的矮边判断。

总结

双指针问题,较低时间复杂度解题的关键在于如何初始化指针位置以及找到如何移动指针的策略。例如这一题在于初始化指针为第一个元素和最后一个元素,同时分别找到最矮边移动以计算最大值。我文章中的前一题,移动零问题,在于初始化指针都为数组开头,然后移动一个指针寻找非零0,另一个指针定位下一个非零值存放的位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12747.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组 数三角

//枚举顶点。 //不存在等边三角形 #include<bits/stdc.h> using namespace std; #define int long long const int n2e311; int a,b,c,l[n],r[n]; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a;for(int i1;i<a;i){cin>>…

UE4_环境_局部雾化效果

学习笔记&#xff0c;不喜勿喷&#xff01;侵权立删&#xff01;祝愿大家生活越来越好&#xff01; 本文重点介绍下材质节点SphereMask节点在体积雾中的使用方法。 一、球体遮罩SphereMask材质节点介绍&#xff1a; 球体蒙版&#xff08;SphereMask&#xff09; 表达式根据距…

2024红帽全球峰会:CEO行业洞察分享

作为全球IT领域一年一度的行业盛宴&#xff0c;2024红帽全球峰会于近日盛大召开。生成式AI与大模型是当前IT行业最受关注的热点话题&#xff0c;而红帽在生成式AI与大模型领域的最新动作&#xff0c;也理所当然地成为了本届峰会观众目光聚集的焦点。 作为世界领先的开源解决方案…

使用vcpkg与json文件自动安装项目依赖库

说明 本文记录自己使用vcpkg.json文件自动安装依赖库并完成编译的全过程。 关于vcpkg是什么这里就不多详细解释&#xff0c;可以看一下专门的介绍及安装的文章&#xff0c;总之了解这是一个C的包管理工具就可以了。 流程 下面介绍从GitHub上克隆C项目以及为这个项目安装所需…

二叉树的常见操作

建立树 复制二叉树 计算深度 计算总结点数 计算叶子结点数

OpenHarmony标准设备应用开发(二)——布局、动画与音乐

本章是 OpenHarmony 标准设备应用开发的第二篇文章。我们通过知识体系新开发的几个基于 OpenHarmony3.1 Beta 标准系统的样例&#xff1a;分布式音乐播放、传炸弹、购物车等样例&#xff0c;分别介绍下音乐播放、显示动画、动画转场&#xff08;页面间转场&#xff09;三个进阶…

AI工具的热门与卓越:揭示AI技术的实际应用和影响

文章目录 每日一句正能量前言常用AI工具创新AI应用个人体验分享后记 每日一句正能量 我们在我们的劳动过程中学习思考&#xff0c;劳动的结果&#xff0c;我们认识了世界的奥妙&#xff0c;于是我们就真正来改变生活了。 前言 随着人工智能&#xff08;AI&#xff09;技术的快…

深度剖析MyBatis的二级缓存

二级缓存的原理 MyBatis 二级缓存的原理是什么&#xff1f; 二级缓存的原理和一级缓存一样&#xff0c;第一次查询会将数据放到 缓存 中&#xff0c;然后第二次查询直接去缓存读取。但是一级缓存是基于 SqlSession 的&#xff0c;二级缓存是基于 mapper 的 namespace 的。也就是…

Qt运行时,如何设置第一个聚焦的控件

问题&#xff1a;Qt第一个聚焦的控件&#xff0c;如何自行设置&#xff1f; 尝试&#xff1a; 1.在代码中设置 lineEdit->setFocus() 。无效&#xff01; 2.Qt Designer–打开form1.ui–菜单栏下一行–Edit Tab Order–按顺序点击–菜单栏下一行–Edit Widgets–退出。无效…

【easyX】动手轻松掌握easyX 1

01 简单绘图 在这个程序中&#xff0c;我们先初始化绘图窗口。其次&#xff0c;简单绘制两条线。 #include <graphics.h>//绘图库头文件 #include <stdio.h> int main() {initgraph(640, 480);//初始化640✖480绘图屏幕line(200, 240, 440, 240);//画线(200,240)…

MySQL是如何选择索引的?

2.3.5. 索引选择 MySQL是如何选择索引的&#xff1f; 优化器决定了具体某一索引的选择&#xff0c;也就是常说的执行计划。而优化器的选择是基于成本&#xff08;cost&#xff09;&#xff0c;哪个索引的成本越低&#xff0c;优先使用哪个索引。 SQL 优化器会分析所有可能的执…

开放式运动耳机哪款好用?五款高性能值得信赖产品推荐

身为户外运动的达人&#xff0c;我发现开放式运动耳机简直是咱们运动时的最佳拍档&#xff0c;不管是跑步还是健身&#xff0c;开放式运动耳机最为舒适&#xff0c;它的妙处就在于不用塞进耳朵&#xff0c;这样既安全又卫生&#xff0c;户外动起来更放心。但市面上好坏参半&…

【半夜学习MySQL】内置函数(含日期、字符串、数学等函数常用用法介绍及示例详解)

&#x1f3e0;关于专栏&#xff1a;半夜学习MySQL专栏用于记录MySQL数据相关内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 日期函数字符串函数数学函数其他函数 日期函数 函数名称描述current_date()当前日期current_time()当前时间current_time()…

幻兽帕鲁Palworld服务器手动部署

目录 帕鲁官方文档手动安装steamcmd通过steamcmd安装帕鲁后端客户端连接附录&#xff1a;PalServer.sh的启动项附录&#xff1a;配置文件 帕鲁官方文档 https://tech.palworldgame.com/ 手动安装steamcmd 创建steam用户 sudo useradd -m steam sudo passwd steam下载steamc…

你写HTML的时候,会注重语义化吗?

其实说到语义化&#xff0c;多年前端开发经验的老手估计也不会太在意&#xff0c;有时候工期太紧&#xff0c;有时候自己疏忽&#xff0c;也就不那么在意了&#xff0c;直接DIVCSS一把梭下去了。 目录 什么是HTML 什么是HTML语义化 HTML语义化所带来的好处 我把CSS样式引入…

_pickle.UnpicklingError: STACK_GLOBAL requires str

导致这个报错的原因是我跑yolo的时候修改数据集了&#xff0c;里面的label.cache没有删除&#xff0c;咱只要删除掉缓存就行&#xff01;&#xff01; 我这里是已经删除掉了&#xff0c;所以图片里面没有&#xff0c;一般就是在箭头所示位置有.cache文件的

Vue3知识总结-4

Vue3知识总结-4 文章目录 Vue3知识总结-4插槽Slots渲染作用域默认内容具名插槽插槽中的数据传递具名插槽传递数据 组件声明周期声明周期示意图 组件生命周期的应用动态组件组件保持存活组件被卸载 异步组件依赖注入 插槽Slots 在某些场景中&#xff0c;可能想要为子组件传递一…

xxljob分片广播+多线程实现高效定时同步elasticsearch索引库

需求&#xff1a;为了利用elasticsearch实现高效搜索&#xff0c;需要将mysql中的数据查出来&#xff0c;再定时同步到es里&#xff0c;同时在同步过程中通过分片广播多线程提高同步数据的效率。 1. 添加映射 使用kibana添加映射 PUT /app_info_article {"mappings&quo…

HL7协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.介绍2.传输协议规范2.1. MLLP2.1.1. 数据头定义2.1.2. 转义字符集 2.2. 规范说明2.3. 消息格式说明 3.HL7结构介绍3.1. 患者建档&#xff08;ADT^A28&#xff09;…

人工智能领域向量化技术加速多模态大模型训练与应用

目录 前言1、TextIn文档解析技术1.1、文档解析技术1.2、目前存在的问题1.2.1、不规则的文档信息示例 1.3、合合信息的文档解析1.3.1、合合信息的TextIn文档解析技术架构1.3.2、版面分析关键技术 Layout-engine1.3.3、文档树提取关键技术 Catalog-engine1.3.4、双栏1.3.5、非对称…