一 🏠 题目描述
1.1 盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器
示例 1:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pf8u9Mlb-1669536211436)(刷爆力扣之盛最多水的容器.assets/question_11.jpg)]
输入:[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
提示:
n == height.length 2 <= n <=1050 <= height[i] <=104
二 🏠破题思路
2.1 🚀 关键信息
解决问题第一步,当然先提取题目字面上的关键信息 😎😎😎
题干很容易理解,找出两条线,使之与 x 轴构成的容器容纳最多的水
即在整数数组 height 中不断寻找两点并计算面积(两点的面积 = 两点的较小高度 * 两点之间距离)
area = min(height[x1] , height[x2]) * (x2 - x1)
比较各个面积,然后返回最大的面积
提取完题目中的关键信息后,直接进入第二阶段,思路整理 😃😃😃
2.2 🚀 思路整理
对于任意两点,固定一点,使另一点向中间移动一位。如果我们移动高度较大的点,那么就相当于高度没有变化(两点的较小高度),而移动后距离反而减小了,那么面积必定会减小
因此,固定一点,使另一点向中间移动一位的过程中,每一步只能移动高度较小点
即循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积
整理完解题思路后,直接进入第三阶段,代码实现 😃😃😃
三 🏠 代码详解
3.1 🚀 代码实现
按照我们刚才的破题思路,直接代码走起来 👇👇👇👇
int maxArea(std::vector<int>& height) { int len = height.size(); //获取输入数组长度 int maxAreaVal =0, left =0, right = len -1; //定义最大面积,左端索引,右端索引 while (left != right) { //循环直至两指针相遇跳出 maxAreaVal = height[left] > height[right] ? //更新面积最大值 std::max((right - left) * height[right--], maxAreaVal) : //将右短板向内移动一格 std::max((right - left) * height[left++], maxAreaVal); //将左短板向内移动一格 } return maxAreaVal; //最大面积 }
3.2 🚀 细节解析
看完 👀👀👀 全注释版的代码实现后,相信看官大大对整体逻辑已经是大写的 OK 了 😃😃😃
那么我们挖掘上述实现的晦涩细节 😖😖😖 进行解析,直接开干,走起来 👇👇👇👇
maxAreaVal = height[left] > height[right] ? //更新面积最大值 std::max((right - left) * height[right--], maxAreaVal) : //将右短板向内移动一格 std::max((right - left) * height[left++], maxAreaVal); //将左短板向内移动一格
这段循环每轮将短板向内移动一格,并更新面积最大值的操作,不使用三元表达式。用逻辑判断的方式 if ( height[left] > height[right] ) . . . ,当然也是 OK 的 😜😜😜,博主个人感觉这样写更优美一点而已
四 🏠 心路历程
为方便各位看官大大了解博主真实刷题过程,我把当时状态纯纯真实还原,记录在心路历程这一小节,不感兴趣的小伙伴可以直接跳过哈
博主在第一阶段提取 🚀 关键信息并没有问题,在第二阶段 🚀 思路整理中首先排除了暴力破解(认为性能必定达不到要求,未尝试),数组类型算法题很多题目都有考查双指针,也是通过这点联想到循环每轮将短板向内移动一格(破题点)的逻辑
但是代码实现的时候未想到使用三元表达式简化代码 😭😭😭 ,代码如下 👇👇👇👇
int maxArea(vector<int>& height) { int len = height.size(); int maxAreaVal =0, left =0, right = len -1; while (left != right) { if (height[left] > height[right]) { //自己实现版本,用的逻辑判断,评论区看到更优雅实现遂改之 maxAreaVal = std::max(height[right] * (right - left), maxAreaVal); --right; } else { maxAreaVal = std::max(height[left] * (right - left), maxAreaVal); ++left; } } return maxAreaVal; }