11.盛最多水的容器
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2
目标:最大面积
显然本题是寻找水覆盖的最大面积=height*width 其中height=min(ai,aj)
条件
两条直线围成高度由最短的那条决定
临界
我们选取两端的直线作为初始状态,此时width是最大的,假设如图所示情况
当前柱子是最两侧的柱子,水的宽度 dd 为最大,其他的组合,水的宽度都比这个小。 左边柱子较短,决定了水的高度为 3。如果移动左边的柱子,新的水面高度不确定,一定不会超过右边的柱子高度 7。 如果移动右边的柱子,新的水面高度一定不会超过左边的柱子高度 3,也就是不会超过现在的水面高度。由此可见,如果固定左边的柱子,移动右边的柱子,那么水的高度一定不会增加,且宽度一定减少,所以水的面积一定减少。这个时候,左边的柱子和任意一个其他柱子的组合,其实都可以排除了。也就是我们可以排除掉左边的柱子了。
但是这里的排除是对于移动方式的排除,不能确定接下来有比它大的,中间我们肯定需要一个max变量来记录最大值
#include<algorithm>//包含max,min函数 leetcode上默认有这个头文件可以不写
class Solution {
public:
int maxArea(vector<int>& height) {
int area=0,max_area=0;
int i=0,j=height.size()-1; //初始选取两端值
while(i<j){ //从两端向中间遍历可能情况,直到i,j相遇
area=(j-i)*min(height[i],height[j]); //当前情况下的面积 也可以理解为上次移动后的area
max_area=max(area,max_area); //更新最大值 max_area之前存的是上一次移动前记录的最大值
if(height[i]<height[j]){ //左小右大 移动左边
++i;
}
else{ //否则移动右边柱子
--j;
}
}
return max_area;
}
};
初始编完时的小错误
开始初始化area,max_area时忘了赋值为零,导致一直无法通过,大家一定要注意赋初始值,否则你的变量初始值的随机性会干扰你的结果。