一级标题
题目: 11. 盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量
暴力解法
遍历找最大即可
class Solution {
public:
int maxArea(vector<int>& height) {
//i点 j点 (k-j)*min(height[k-1],height[j-1]) = temp ; ans=max(ans,temp)
int ans=1,temp =0;
for(int i=0;i<height.size()-1;i++){
for(int j=i+MinIntervals;j<height.size();j++){
temp=(j-i)*min(height[i],height[j]);
ans=max(ans,temp);
}
}
return ans;
}
};
稍微改进一点,计算最小间隔MinIntervals(两个点的距离);
//两个语法问题:
//1、double转int、int a=int/int,其结果都是舍去小数取整。
//2、max_element() 可以用来找整个数组的最大元素;max()找两个数的最大值;
//要注意的是begin()end()返回的是迭代器(指针)类型,因此记着加上*,得到的才是最大值。
vector<int>& height;
int min=(min(height[0],height[height.size()-1])
int max= *max_element(height.begin(),height.end())
int d = *min(height.begin(),height.end());//此时是比较指针大小,不是想要的结果
class Solution {
public:
int maxArea(vector<int>& height) {
//i点 j点 (k-j)*min(height[k-1],height[j-1]) = temp ; ans=max(ans,temp)
int ans=(height.size()-1)*(min(height[0],height[height.size()-1])),temp =0;
int MinIntervals =1;
MinIntervals =ans/(*max_element(height.begin(),height.end())); //这里是向下取整的
if (MinIntervals <0) MinIntervals=1;
for(int i=0;i<height.size()-1;i++){
for(int j=i+MinIntervals;j<height.size();j++){
temp=(j-i)*min(height[i],height[j]);
ans=max(ans,temp);
}
MinIntervals =ans/(*max_element(height.begin(),height.end()));
}
return ans;
}
};
双指针
上面第二个解法是从最小间隔上考虑的,双指针解法是从两个点的移动上考虑。
开始时a指针指向begin,b指向end,两者的较小值向彼此移动,直至靠近(或者最小间隔)。关键一点是这样做为何能找到最大面积?难道不会错过某种情况么,如果移动较大值,保持较小值不变,显然随着距离越近,面积只会越来越小。再加上两者从两端向中间靠拢,不会错过更大的面积,错过的只会是更小的面积。
class Solution {
public:
int maxArea(vector<int>& height) {
int l = 0, r = height.size() - 1;
int ans = 0;
while (l < r) {
int area = min(height[l], height[r]) * (r - l);
ans = max(ans, area);
if (height[l] <= height[r]) {
++l;
}
else {
--r;
}
}
return ans;
}
};