题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
示例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
示例3
输入:height = [4,3,2,1,4]
输出:16
示例4
输入:height = [1,2,1]
输出:2
提示
1. n == height.length
2. 2 <= n <= 105
3. 0 <= height[i] <= 104
思路
之前我们一直在做回溯搜索,今天我们来换换脑子,今天做的是一道贪心算法的题目,解法也是很经典的双指针算法
首先我们看题目,大概就是有n个柱子,每根柱子的长度是ai,每根柱子和左右柱子的间距都为1,要求我们找到两个柱子之间最大的面积
面积是指两个柱子之间较矮的柱子作为宽,两柱子之间的距离为长形成的矩形的面积
那我们的目的很明确,就是要找到两个柱子(二者之中较矮的那个在所有柱子中也是较高的),并且这两个柱子的距离还较远,这样才能让面积更大
接下来我们看代码
代码
在主要实现细节这里,我们该如何控制变量呢?这里有两个我们需要考虑的因素
1.是要保证形成的矩形的宽最大
要实现宽最大,其实就需要两个柱子的高度相近,我们设置两个指针,分别指向数组两端,如果一端比另一端短,则我们移动较短的那端的指针,来寻找比长端更长的柱子
2.是要保证两根柱子之间的距离最大
我们无法保证当宽度最大的时候距离也最大,因此我们需要遍历,两个指针在两端时距离最大,然后随着不断的移动距离变得更小,核心就在于每次移动短端指针会有可能找到一个比当前最大面积的更大面积
int i = 0; int j = n - 1;
定义指向数组两端的指针,一个值为0,一个为数组末端
当左端指针小于右端指针的时候保持循环
完整代码
class Solution {
public:
int maxArea(vector<int>& height) {
int n = height.size();
int i = 0;
int j = n - 1;
int ans = 0;
while(i < j) {
ans = max((j - i) * min(height[i], height[j]), ans);
if(height[i] > height[j]) {
--j;
}else {
++i;
}
}
return ans;
}
};