题目描述
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
示例:

输入: [1,8,6,2,5,4,8,3,7]
输出: 49
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
解题思路
- 首先我看到这个题目,没啥思路,也没有一个很好的切入点,一开始想的是使用双窗口,因为这题的本质就是确定两个点嘛,那么我就想着使用滑动窗口,然后这个窗口就表示面积最大的两个点,但是最后证实是不可行的,其中的原因有:新加入的点不单单与窗口的start位置能组成最大矩形面积,与窗口中的各个点也都有可能组成最大矩形面积,所以滑动窗口的思路并不能使用
- 接下来我观察实例,发现一个规律:新加入的点如果比当前组成最大矩形面积的两个点中的第一个点小,那么只需要比较新加入点与第一个点组成的矩形面积与当前最大矩形面积相比较即可,举个例子:
例如,目前矩形最大面积由8和6两个点构成,此时矩形最大面积为6,当新加入2时,因为比8小,所以我们只需要比较8和2构成的矩形面积和6相比较,当大于时,那么更新矩形最大面积,否则继续遍历下一个点(为什么当新加入点比第一个点小就只需要比较两个矩形面积的大小,理由如下:当新加入点比第一个点小时,例如2小于8,那么8的下一个点如果比2大,如6,因为矩形面积都是以短的边长作为高,所以只要比2大,那么高都是2,但是你的底减小了;当8的后面的点比2小时,那么你的矩形的高和底相比较来说都减小了,所以总的来说,当新加入的点比此时矩形最大面积构成的那两个点的第一个点小时,我们只需要比较新的矩形和此时矩形最大面积的大小即可)
那么对于新加入点大于第一个点的情况怎么解决呢?当时我是这样解决的:矩形里面的所有点与新加入点分别构成不同的矩形,取最大的那个矩形,代码如下:
int maxArea(vector<int>& height) {
int result = height[0] > height[1] ? height[1] : height[0];//首先比较最开始的两个点,取值小的那个点
int i = 2, t = 0,mem;
int x = t;
while (i<height.size()) {
if (height[i] < height[t]) { //这里是新加入的点比第一个点小的情况
mem = (i - t) * height[i];
if (mem > result)
result = mem;
}
else { //这里是另外一种情况
while (t < i) {
if (height[i] < height[t])
mem = (i - t) * height[i];
else
mem = (i - t) * height[t];
if (mem >= result) {
result = mem;
x = t;
}
t++;
}
t = x;
}
i++;
}
return result;
}
结果示例是通过了,但是对于数量很多的实例却不能得到正确答案,因为对于vector中元素数量很多的例子,因为数量太多,所以也不能调试,所以我也不懂错误在哪里,但是理了一遍思路,发现确实值得推敲,也不值得推敲,可能也不是一种好的办法
3. 接下来就想到了:可不可以从两端往内收缩(因为曾经有思路是利用递归,从中间向两端扩散,发现这种思路也不正确),直接上代码:
int maxArea(vector<int>& height) {
int size = height.size()-1;
int result =size*( height[0] > height[size] ? height[size] : height[0]);//这里保存的是两端端点构成的矩形面积
int min = height[0] > height[size] ? size : 0;//min表示矩形两条边中短的一条的下标
int i = 0,t=size;
while (i != t) {
//移动的永远是短的那一边
if (min==i) {
i++;
while (min != t&&height[min]>height[i]) //只要边比用来比较的那一条边短,直接跳过
i++;
}
else {
t--;
while (min != i && height[min] > height[t])
t--;
}
min = height[i] > height[t] ? t : i;//当出现较大的边时,便更新min值
if ((t - i) * height[min] > result)
result = (t - i) * height[min];
}
return result;
}
总结:矩形面积等于底x高,那么我们向中间收缩的过程中,相当于底边减小,那么要想矩形的面积变大,那么你只能寻找高变大的那一个才有可能实现矩形面积增大
581

被折叠的 条评论
为什么被折叠?



