1 问题
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.
2 分析
这道题LeetCode网站中给出的解法为 双指针法,双指针法在处理字符串类的问题中非常常见。这里着重从数学的角度分析该题目的解法。设容器的面积为
S
, 且容器由
题目求的是在不同 i,j 下,面积 S 的最大值。如果能够求出函数
下面根据 ai,aj 的相对大小讨论不同的 i,j 导致 S 的变化情况:
- 如果
ai≥aj , 移动 ai 到 ai+1 :
- 如果 ai+1≥ai ,那么 Si+1,j=Si,j (根据S的公式容易判断)
- 如果
ai+1<ai
, 那么
Si+1,j<Si,j
即在这种情况下,移动 ai 一定不会导致 Si,j 的面积增加
- 如果
ai<aj
, 移动
ai
到
ai+1
:
- 如果 ai<ai+1<aj , 那么 Si+1,j 的面积有可能大于 Si,j
- 如果 ai<aj<ai+1 , 那么 Si+1,j 的面积一定大于 Si,j
- 如果 ai+1<ai<aj , 那么 Si+1,j 的面积一定小于 Si,j
根据上述讨论,只有在2.1和2.2的情况下, Si,j 是单调增加的。因此可以将 i,j 分别指向数组的最左和最右端,只按照2.1和2.2的规律来移动 i,j , 便能够求出 S <script id="MathJax-Element-40" type="math/tex">S</script> 的最大值。
3 代码
public class Solution { public int maxArea(int[] height) { int maxarea = 0, l = 0, r = height.length - 1; while (l < r) { maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l)); if (height[l] < height[r]) l++; else r--; } return maxarea; } }
[1]代码来源于LeetCode: https://leetcode.com/articles/container-most-water/