盛最多水的容器[中等]

一、题目

给定一个长度为n的整数数组height。有n条垂线,第i条线的两个端点是(i, 0)(i, height[i])。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。也就是求x轴与y轴的面积。

说明:你不能倾斜容器。

示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组[1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为49

示例 2:
输入:height = [1,1]
输出:1

二、代码

我们先从题目中的示例开始,一步一步地解释双指针算法的过程。稍后再给出算法正确性的证明。

题目中的示例为:

[1, 8, 6, 2, 5, 4, 8, 3, 7]
 ^                       ^

在初始时,左右指针分别指向数组的左右两端,它们可以容纳的水量为min⁡(1,7)∗8=8

此时我们需要移动一个指针。移动哪一个呢?直觉告诉我们,应该移动对应数字较小的那个指针(即此时的左指针)。这是因为,由于容纳的水量是由

两个指针指向的数字中较小值∗指针之间的距离

决定的。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。因此,我们移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针。

::: tip
有读者可能会产生疑问:我们可不可以同时移动两个指针? 先别急,我们先假设 总是移动数字较小的那个指针 的思路是正确的,在走完流程之后,我们再去进行证明。
:::

所以,我们将左指针向右移动:

[1, 8, 6, 2, 5, 4, 8, 3, 7]
    ^                    ^

此时可以容纳的水量为min⁡(8,7)∗7=49。由于右指针对应的数字较小,我们移动右指针:

[1, 8, 6, 2, 5, 4, 8, 3, 7]
    ^                 ^

此时可以容纳的水量为min⁡(8,3)∗6=18。由于右指针对应的数字较小,我们移动右指针:

[1, 8, 6, 2, 5, 4, 8, 3, 7]
    ^              ^

此时可以容纳的水量为min⁡(8,8)∗5=40。两指针对应的数字相同,我们可以任意移动一个,例如左指针:

[1, 8, 6, 2, 5, 4, 8, 3, 7]
       ^           ^

此时可以容纳的水量为min⁡(6,8)∗4=24。由于左指针对应的数字较小,我们移动左指针,并且可以发现,在这之后左指针对应的数字总是较小,因此我们会一直移动左指针,直到两个指针重合。在这期间,对应的可以容纳的水量为:min⁡(2,8)∗3=6min⁡(5,8)∗2=10min⁡(4,8)∗1=4

在我们移动指针的过程中,计算到的最多可以容纳的数量为49,即为最终的答案。

为什么双指针的做法是正确的?

双指针代表了什么?

双指针代表的是 可以作为容器边界的所有位置的范围。在一开始,双指针指向数组的左右边界,表示 数组中所有的位置都可以作为容器的边界,因为我们还没有进行过任何尝试。在这之后,我们每次将 对应的数字较小的那个指针 往 另一个指针 的方向移动一个位置,就表示我们认为 这个指针不可能再作为容器的边界了。

为什么对应的数字较小的那个指针不可能再作为容器的边界了?

在上面的分析部分,我们对这个问题有了一点初步的想法。这里我们定量地进行证明。

考虑第一步,假设当前左指针和右指针指向的数分别为xy,不失一般性,我们假设x≤y。同时,两个指针之间的距离为t。那么,它们组成的容器的容量为:min⁡(x,y)∗t=x∗t

我们可以断定,如果我们保持左指针的位置不变,那么无论右指针在哪里,这个容器的容量都不会超过x∗t了。注意这里右指针只能向左移动,因为 我们考虑的是第一步,也就是 指针还指向数组的左右边界的时候。

我们任意向左移动右指针,指向的数为y1​,两个指针之间的距离为t1​,那么显然有t1<t,并且min⁡(x,y1)≤min⁡(x,y)
【1】如果y1≤y,那么min⁡(x,y1)≤min⁡(x,y)
【2】如果y1>y,那么min⁡(x,y1)=x=min⁡(x,y)

因此有:min⁡(x,yt)∗t1<min⁡(x,y)∗t

即无论我们怎么移动右指针,得到的容器的容量都小于移动前容器的容量。也就是说,这个左指针对应的数不会作为容器的边界了,那么我们就可以丢弃这个位置,将左指针向右移动一个位置,此时新的左指针于原先的右指针之间的左右位置,才可能会作为容器的边界。

这样以来,我们将问题的规模减小了 111,被我们丢弃的那个位置就相当于消失了。此时的左右指针,就指向了一个新的、规模减少了的问题的数组的左右边界,因此,我们可以继续像之前 考虑第一步 那样考虑这个问题:
【1】求出当前双指针对应的容器的容量;
【2】对应数字较小的那个指针以后不可能作为容器的边界了,将其丢弃,并移动对应的指针。

最后的答案是什么?

答案就是我们每次以双指针为左右边界(也就是「数组」的左右边界)计算出的容量中的最大值。

双指针: 定义两个指针leftright, 不断移动hegiht[x]值小的一方。直到left >= right

class Solution {
    public int maxArea(int[] height) {
        // 定义两个指针left 和 right, 不断移动 hegiht[x] 值小的一方
        int left = 0, right = height.length - 1, area = 0;
        while(left < right) {
            area = Math.max(area, (right - left) * Math.min(height[left],height[right]));
            if (height[left] < height[right]) {
                ++left;
            } else {
                --right;
            }
        }
        return area;
    }
}

时间复杂度: O(N),双指针总计最多遍历整个数组一次。
空间复杂度: O(1),只需要额外的常数级别的空间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 获取计算机信息

目录 一、本机信息 1、本机名 2、获得本机MAC地址 3、获得计算机名 4、显示器分辨率 5、主显示器分辨率 6、系统路径 二、操作系统信息 1、操作系统类型 2、获得操作系统位数 3、获得操作系统版本 三、处理器信息 1 、处理器个数 四、CPU信息 1、CPU的个数 2、…

C语言推荐新手学习吗?

今日话题&#xff0c;C语言推荐新手学习吗&#xff1f;我自己当年是从BASIC入门编程的&#xff0c;回顾起来&#xff0c;BASIC的确是一门非常容易入门的语言。它让初学者能够专注于编写程序本身&#xff0c;而不必过多关注细节。Pascal也是一门较易入门的语言&#xff0c;比C语…

C语言-指针的基本知识(上)

一、关于内存 存储器&#xff1a;存储数据器件 外存 外存又叫外部存储器&#xff0c;长期存放数据&#xff0c;掉电不丢失数据 常见的外存设备&#xff1a;硬盘、flash、rom、u盘、光盘、磁带 内存 内存又叫内部存储器&#xff0c;暂时存放数据&#xff0c;掉电数据…

eclipse启动Java服务及注意事项

一、eclipse导入java项目并配置 1、导入项目 选择file——》import…——》Generate——》Exiting Projects into Workspace——》选择要导入的项目 2、添加tomcat 1&#xff09;点击Serves——》No servers are available. Click this link to create a new server… 2&…

为什么要用云手机养tiktok账号

在拓展海外电商市场的过程中&#xff0c;许多用户选择采用tiktok短视频平台引流的策略&#xff0c;以提升在电商平台上的流量&#xff0c;吸引更多消费者。而要进行tiktok引流&#xff0c;养号是必不可少的一个环节。tiktok云手机成为实现国内跨境养号的一种有效方式&#xff0…

Jenkins如何从GIT下拉项目并启动Tomcat

一、先添加服务器 二、添加视图 点击控制台输出&#xff0c;滑到最下面&#xff0c;出现这个就说明构建成功了&#xff0c;如果没有出现&#xff0c;说明构建有问题&#xff0c;需要解决好问题才能启动哦~

SpringBoot 实现自定义指标监控

一、添加业务监控指标 在 spring-web-prometheus-demo 项目的基础上&#xff0c;我们添加一个 PrometheusCustomMonitor 类。在这里面我们定义了三个业务指标&#xff1a; order_request_count&#xff1a;下单总次数order_amount_sum&#xff1a;下单总金额 Component publ…

Python判断语句——if语句的基本格式

一、引言 在Python编程语言中&#xff0c;if语句是一种基本的控制流语句&#xff0c;用于根据特定条件执行不同的代码块。它的基本格式相对简单&#xff0c;使得Python代码清晰、易于阅读。下面&#xff0c;我们将深入探讨if语句的基本格式、用法和注意事项。 二、if语句的…

如何搭建Nextcloud云存储网盘并实现无公网ip访问本地文件【内网穿透】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

为什么说2023年是AI元年

前言 思考者~ 2023年被称为AI元年&#xff0c;主要是因为在这一年中&#xff0c;人工智能技术在各个领域取得了突破性的进展和应用&#xff0c;这些技术的广泛应用深刻地影响了人们的生活和工作方式&#xff0c;也预示着未来AI技术的更大潜力和发展空间。 首先&#xff0c;…

Delphi.cz采访​Embarcadero​捷克共和国办事处经理:理查德·库巴特 - 第一部分

Embarcadero捷克办事处主任理查德库巴特&#xff08;Richard Kubt&#xff0c;55 岁&#xff09;接受了我的采访。 Radek Červinka (RČ)&#xff1a;库巴特先生您好&#xff0c;感谢您抽出时间访问 delphi.cz。 一开始&#xff1a;我在某处听说您是一名程序员&#xff0c;从…

Idea设置代理后无法clone git项目

背景 对于我们程序员来说&#xff0c;经常上github找项目、找资料是必不可少的&#xff0c;但是一些原因&#xff0c;我们访问的时候速度特别的慢&#xff0c;需要有个代理&#xff0c;才能正常的访问。 今天碰到个问题&#xff0c;使用idea工具 clone项目&#xff0c;速度特…

Windows系统本地安装Everything搜索神器并结合内网穿透实现远程访问

文章目录 前言1.软件安装完成后&#xff0c;打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前言 要搭建一个在线资料库&#xff0c;我们需要两个软件的支持&#xff0c;分别是cpolar&#xff08;用于搭建内网穿透数据隧道…

洛谷 P1433 吃奶酪 状态压缩dp

文章目录 题目链接题目描述解题思路代码实现总结 题目链接 链接: P1433 吃奶酪 题目描述 解题思路 首先&#xff0c;这个程序是用来解决洛谷上题目编号为 P1433 的问题——吃奶酪&#xff0c;使用了状压DP算法。 整体算法的思路是利用动态规划&#xff0c;通过状态压缩来解…

树莓派部署Nginx服务结合内网穿透实现远程访问本地站点

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

TF卡在心电监测仪中的多功能应用

TF卡在心电监测仪中的应用 TF卡&#xff08;Micro SD卡&#xff09;在心电仪器上的应用主要是用作存储设备&#xff0c;用于保存心电信号数据和其他相关信息。以下是TF卡在心电仪器上的一些常见应用&#xff1a; 1、数据存储&#xff1a; TF卡用于存储从心电仪器采集到的心电信…

SRC实战 | 后台登录绕过分享

本文由掌控安全学院 - 小袅投稿 一.挖掘过程简述&#xff1a; 通过收集到的账号密码进入后进行测试无果&#xff0c;查看登录返回包后修改role_id参数进入管理员后台&#xff0c;后台存在文件上传功能且对文件后缀和内容有检查&#xff0c;后缀检测时前端进行的&#xff0c;可…

c#之构值类型和引用类型

值类型:(整数/bool/struct/char/小数) 引用类型:(string/ 数组 / 自定义的类 / 内置的类) 值类型只需要一段单独的内存,用于存储实际的数据 引用类型需要两段内存(第一段存储实际的数据,他总是位于 堆中第二段是一个引用,指向数据在堆中的存放位置) 当使用引用类型赋值的时…

【Python自动化测试】如何才能让用例自动运行完之后,生成一张直观可看易懂的测试报告呢?

小编使用的是unittest的一个扩展HTMLTestRunner 环境准备 使用之前&#xff0c;我们需要下载HTMLTestRunner.py文件 点击HTMLTestRunner后进入的是一个写满代码的网页&#xff0c;小编推荐操作&#xff1a;右键 --> 另存为&#xff0c;文件名称千万不要改 python3使用上述…

LeetCode.209. 长度最小的子数组

题目 题目链接 分析 本题的题意就是让我们找最短的子数组和 > target 的子数组的长度。 首先最能想到的就是暴力方法&#xff0c;外层循环以数组每一个元素都作为起点&#xff0c;内存循环累加元素&#xff0c;当大于等于 target 的时候记录当前元素个数&#xff0c;更新…