题目:
Given n non-negative integers a1, a2, …, an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
解答:
本题采用双指针的解法,双指针避免了采用双循环嵌套的大量的搜索,降低了时间复杂度。
- 创建双指针i,j,指针 i 指向数组的头部,从头至尾遍历,指针 j 指向数组的尾部,从尾至头遍历,直至 i=j
- 使用变量 maxarea 来持续存储到目前为止所获得的最大容量
- 若 height[i] <= height[j],计算当前能容纳的最大水量,并 i++;若 height[i] <= height[j],计算当前能容纳的最大水量,并 j–,若当前最大水量 > maxarea,则更新 maxarea 的值
class Solution {
public int maxArea(int[] height) {
int i = 0;
int j = height.length-1;
int maxarea = 0;
int temp = 0;
while(i<j) {
if(height[i] <= height[j]) {
temp = (j-i) * height[i];
i++;
} else {
temp = (j-i) * height[j];
j--;
}
maxarea = (temp > maxarea) ? temp :maxarea;
}
return maxarea;
}
}
注意:
这种指针移动的方法,其实并没有遍历出所有容器的情况,比如若 height [i] <= height [j],则直接 i++,这样就遗漏了 height [i] 与height [i+1,…,j-1] 之间某个数构成最大盛水容器的可能性。
但可以证明, height [i] 与height [i+1,…,j-1] 之间某个数构成的容器不会是最大值。
假设存在 k,k 满足 i+1 <= k <= j-1,height [i] 与 height [k] 构成了最大盛水容器,容量为 C。
- 如果 height [i] <= height [k],则 C = height [i] × (k - i),而 height [i] 和 height [j] 构成的盛水容器容量为 height [i] × (j - i) > C。因此这种情况下 C 不会成为最大容量。
- 如果 height [i] > height [k],则 C = height [k] × (k - i),因为 height [i] < height [j], 所以height [j] > height [i] > height [k],所以 height [i] 和 height [j] 构成的盛水容器容量为 height [i] × (j - i) > C。因此这种情况下 C 仍不会成为最大容量。
综上可得,height [i] 不可能与 height [i+1,…,j-1] 之间的某个数构成最大盛水容器。