LeetCode 11:盛最多水的容器(Container With Most Water)解法汇总

文章目录

  • Approach 1: Brute Force
  • Approach 2: Two Pointer Approach

更多LeetCode题解

Approach 1: Brute Force

class Solution {
public:
	int maxArea(vector<int>& height) {
		int water = 0;
		for (int i = 0; i < height.size() - 1; i++) {
			for (int j = i + 1; j < height.size(); j++) {
				int temp_water = (j - i)*min(height[i], height[j]);
				if (temp_water > water) {
					water = temp_water;
				}
			}
		}
		return water;
	}
};

Approach 2: Two Pointer Approach

这种方法背后的思路在于,两线段之间形成的区域总是会受到其中较短那条长度的限制。此外,两线段距离越远,得到的面积就越大。

最初我们考虑由最外围两条线段构成的区域。现在,为了使面积最大化,我们需要考虑更长的两条线段之间的区域。如果我们试图将指向较长线段的指针向内侧移动,矩形区域的面积将受限于较短的线段而不会获得任何增加。但是,在同样的条件下,移动指向较短线段的指针尽管造成了矩形宽度的减小,但却可能会有助于面积的增大。因为移动较短线段的指针会得到一条相对较长的线段,这可以克服由宽度减小而引起的面积减小。

这是很容易理解的,但是还是有一点疑问,这种方法真的搜索完所有情况了吗?

我们用一个矩阵来表示,横轴和纵轴都表示位置,假设n=6。那么初始对为(1, 6),如果左侧高度小于右侧,那么(1, 2)....(1, 5)都没有必要去检查,因为他们肯定小于(1,6)。从下图可以看到,所有-位置都被我们删去了,不用计算

  1 2 3 4 5 6
1 x ------- o
2 x x
3 x x x 
4 x x x x
5 x x x x x
6 x x x x x x

将1右移得到(2, 6),如果右侧高度小于左侧,那么(3, 6), (4, 6), (5, 6)肯定小于(2, 6),所以直接将6左移,从下图可以看到,所有|位置都被删去,免去计算。

  1 2 3 4 5 6
1 x ------- o
2 x x       o
3 x x x     |
4 x x x x   |
5 x x x x x |
6 x x x x x x

推广可以得到,通过将短边左移或右移,可以免去很多不必要计算的位置。

class Solution {
public:
	int maxArea(vector<int>& height) {
		int water = 0;
		int i = 0, j = height.size() - 1;
		while (i < j) {
			water = max(water, (j - i)*min(height[i], height[j]));
			if (height[i] < height[j]) {
				i++;
			}
			else {
				j--;
			}
		}
		return water;
	}
};

你可能感兴趣的:(LeetCode 11:盛最多水的容器(Container With Most Water)解法汇总)