这个题目的可以通过暴力列举法和双指针,但最好方法是使用双指针,我们可以知道由水桶定律,木桶容纳水的体积是取决于最短的那块木板,木桶的水容还与底面积的大小有关,我们先将指针指向数组的最左右两侧,先判断最短的木板,去求得水桶内可容纳最大的体积,保存这个值,之后是关键的一步,我们需要考虑之后的指针,我们需要怎么移动,自然指针应该是相向移动,同样的,我们期望我们每一次移动,我们都希望这是可能增大水容的,我们不希望每一次的移动是不可能增大水容。
好,现在我们开始考虑,移动的方式一共是三种,1,两个指针一起相向移动,2,较大的值相内部移动,3,较小值相内部移动。
第一种显然不行,因为,最短的木板没有变,但是两个指针的长度缩短了,水桶的水容不可能增大,我们直接pass掉。
第二种,稍微难判断一点,我们可以知道移动之后,两指针的大小判断开始不能确定了,但有一种变量的变化趋势是可以预知的,就是两指针之间的距离是不断变小的,无论移动之后是变大还是变小,木桶水容的高度还是由木桶的最短板确定,所以我们可以知道木桶水容的大小是不可能增大的,可以pass掉。
第三种,尽管已经不需要在分析了,但是还是考虑一下吧,当我们移动后的结果变小了,木桶的水容会变得更小,但是,当移动的结果变大了,我们不能确定木桶的水容大小是否一定会增加,但是这是可能的,这也是我们所期望移动的方向。
我再多嘴一次,我们如果拿到了比上一次更大的值,我们就将它给替换掉,进行下一次的比较,直到拿到最大的值。
java代码:
public class Solution {
int maxArea(int[] height) {
int l = 0, r = height.length() - 1;
int ans = 0;
while (l < r) {
int area = min(height[l], height[r]) * (r - l);
ans = ans>area?ans:area;
if (height[l] <= height[r]) {
++l;
}
else {
--r;
}
}
return ans;
}
};
C++的代码:
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 = ans>area?ans:area;
if (height[l] <= height[r]) {
++l;
}
else {
--r;
}
}
return ans;
}
};
这就是双指针算法的体现。