leetcode 11. 盛最多水的容器 题解

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (iai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (iai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例:

输入: [1,8,6,2,5,4,8,3,7]
输出: 49

我的第一想法很简单,就是暴力搜索加剪枝,时间复杂度仍为O(n^2),但是因为加上了剪枝,所以消耗的时间也不错,但是如果这样就结束的话那刷leetcode也就没有意义了,所以我看了推荐的题解,一般都是推荐的双针法,双针法的时间复杂度为O(n),速度确实快了不少,但是我仍然有点怀疑这个双针法是否针对所有数据都能够找出正确的最大值。因为很明显,双针法无法对所有情况进行一个遍历,到底能不能找到这个最大值呢?或者说它是怎么找到这个最大值的?

后来仔细想一想,这个困扰我的问题是可以用反证法解决的。

首先设左指针为i,右指针为j,以及得到这个最大值的情况左边界为left,右边界为right,他们对应的高度分别为H(left)H(right),此时最大值为H(left)H(right)中的较小值乘以(right-left)。有一点是肯定的,那就是肯定会有一个指针先到达这两个边界其中的一个。

此时有一种情况会导致无法得到这个最大值,首先假设右指针先到达右边界,此时若左边指针指向位置的高度大于这个右指针指向位置的高度,则右指针就会向左移动,就会错过这个右边界,此时肯定就得不到这个最大值了。假设这个情况发生了,此时左指针尚未到达左边界,也就是i<left,因为要符合假设,让右指针左移,所以H(i)>H(right),因此取这个较小值为H(right),此时的盛水量为

H(right)*(right-i),明显比假设的最大值要大(假设的最大值为H(left)*(right-left)H(right)*(right-left)中的较小值,且left>i),此时出现了比我们假设的最大值还要大的值,因此原假设不成立,这个先到达的右指针不会继续往左移动,以至于错过这个右边界,同理可以推广为这两个指针先到达边界的那个在另一个指针到达另一个边界之前不会越过他自己的边界。

扫描二维码关注公众号,回复: 5937639 查看本文章

先放直接暴力搜索的代码:

class Solution {   //暴力搜索+剪枝
public:
	int maxArea(vector<int>& height) {
		int size = height.size();
		int maxWater = 0;
		int leftHeight=height[0], rightHeight=height[size-1];
		for (int i = 0; i < size; i++)
		{
			if (leftHeight <= height[i])
			{
				leftHeight = height[i];
				rightHeight = height[size - 1];
				for (int j = size - 1; j > i; j--)
				{
					if (height[j] >= rightHeight)
					{
						int heightTemp = height[i] < height[j] ? height[i] : height[j];
						int temp = heightTemp * (j - i);
						if (maxWater < temp)
						{
							maxWater = temp;
						}
					}
				}
			}
		}
		return maxWater;
	}
};

再放双针法的代码:

class Solution {  //双针法
public:
	int maxArea(vector<int>& height) {
		int num = height.size();
		if (num < 2) return -1;
		int i = 0;
		int j = num - 1;
		int res = 0;
		while (i != j) {
			int tmp = min(height[i], height[j])*(j - i);
			res = max(res, tmp);
			if (height[i] < height[j]) i++;
			else j--;
		}
		return res;
	}
};

猜你喜欢

转载自blog.csdn.net/qq_38279908/article/details/88669797