题目:
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.
思路:
1、暴力枚举法:显而易见的思路是两重循环,暴力枚举所有可能的containter,时间复杂度为$O(n^2)$。然而显而易见该方法无法通过Leetcode的测试以及面试官。
2、双指针法:首先设置左右两个指针,并初始化当前容器的容量。接着比较左右指针的高低,如果左边更低,则左指针持续右移直到遇到比当前左指针更高的指针;否则右指针左移直到遇到比当前右指针更高的指针,随后更新容量。其原理是:因为我们是从宽度最大的容器开始搜索的,那么要获得更大的容量,唯一的可能就是更新后的min(left, right)大于当前的min(left, right)。上述指针移动的规则正是基于该原理设计的。该方法的时间复杂度为O(n),空间复杂度为O(1)。
代码:
class Solution {
public:
int maxArea(vector<int>& height) {
int left = 0, right = height.size() - 1, index = 0;
int max_area = min(height[left], height[right]) * (right - left);
while(left < right)
{
if(height[left] > height[right]) // decrease right
{
index = right - 1;
while(index > left && height[index] <= height[right])
--index;
right = index;
}
else // increase left
{
index = left + 1;
while(index < right && height[index] <= height[left])
++index;
left = index;
}
max_area = max(max_area, min(height[left], height[right]) * (right - left));
}
return max_area;
}
};