题目分析
- 暴力法:枚举可能的两个柱子,但是会有较多的无效计算(比如枚举的柱子越来越短)
- 优化:双指针,记录两边的柱子的高度,记录面积(=底x高)最大,高取决于矮的柱子
- 最大面积 = max( lr组合的面积 , 最大面积 )
- 左边如果小于右边,那就说明矮的在左边,所以要移动左边,继续找可能大的(移动的永远是矮的那一个)
- 并且如果发现移动之后,高度更小或者相等(底变小了),那么就应该直接跳过
Solution
public int maxArea(int[] height) {
if (height == null || height.length == 0) return 0;
int l = 0, r = height.length - 1, water = 0;
while (l < r) {
int minH = Math.min(height[l], height[r]);
water = Math.max(water, minH * (r - l));
// 下面2个while,一个一定大于minH,直接跳出
while (l < r && height[l] <= minH) l++;
while (l < r && height[r] <= minH) r--;
}
return water;
}
public int maxArea1(int[] height) {
if (height == null || height.length == 0) return 0;
int l = 0, r = height.length - 1, water = 0;
while (l < r) {
if (height[l] <= height[r]) {
int minH = height[l];
water = Math.max(water, (r - l) * minH);
while (l < r && height[l] <= minH) l++;
} else {
int minH = height[r];
water = Math.max(water, (r - l) * minH);
while (l < r && height[r] <= minH) r--;
}
}
return water;
}
Reference:小码哥MJ