11. Container With Most Water

Posted Zzz...y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11. Container With Most Water相关的知识,希望对你有一定的参考价值。

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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.

问题:给出一组非负数组 a1a2, ..., an,ai表示位于位置i的线的高度,用任意两根线装水,求最大值,不能倾斜。

不能倾斜,装水,所以上述问题就是求   res = min(a[i], a[j]) * (j - i)  的最大值,其中 0 <= i < j <= n。

1、最简单最暴力的方法是遍历所有组合了,这样时间复杂度就是O(n2)。

2、想一个复杂度比较小的方法。要使乘积足够大,首先a[i], a[j]要足够大,其次两个数要足够远,也就是(j - i)足够大。从这个方向去解决问题:

设置两个指针,一个从头开始扫,一个从尾部开始,这样能保证(j - i)是最大的。在(j - i)减小的基础上,为了增大res, 需要增大min(a[i], a[j])。

不妨设 a[i] < a[j],所以 ++i, 只要找到a[i + m] > a[i],此时判断哪个面积更大,并在这个基础上继续扫描。

这边有一个问题,就是 假设  res1 = min(a[i], a[j]) * (j - i) < min(a[i + m], a[j]) * (j - i - m) = res2 ,

会不会存在一个n,使得 res3 = min(a[i], a[j - n]) * (j - i - n) > min(a[i + m], a[j]) * (j - i - m) = res2 

因为在上一步, res2 > res1 时,i ← i + m,那么如果存在这种情况,方法2就是不严谨的。

证明:

已知 1、ai<ai+m; 2、a< aj-n; 3、min(ai, aj) * (j - i) < min(ai+m, aj) * (j - i - m)

反证法: 假设存在n, 使res3 > res2

那么就有 res3 > res1

于是 min(ai, aj-n) > min(ai, aj)

情况1:aj-n > ai > aj, 或ai > aj-n > aj

那么可以推出     aj * (j - i)  = min(ai, aj) * (j - i)  > min(ai+m, aj) * (j - i - m) =  aj * (j - i - m) , 与已知条件3矛盾

情况2:aj > ai > aj-n   显然与已知条件2矛盾

 

那么就愉快地发现方法2是严谨的。时间复杂度成功降到O(n)

 1 class Solution {
 2 public:
 3     int maxArea(vector<int>& height) {
 4         if (height.empty())
 5             return 0;
 6         int low = 0;
 7         int high = height.size() - 1;
 8         int res = min(height[low], height[high]) * (high - low);
 9         while (low < high) {
10             if (height[low] < height[high]) {
11                 while (height[low + 1] <= height[low])
12                     ++low;
13                 res = max(res, min(height[++low], height[high]) * (high - low));
14             }  
15             else {
16                 while (height[high - 1] <= height[high])
17                     --high;
18                 res = max(res, min(height[low], height[--high]) * (high - low));
19             }
20         }
21         return res;
22     }
23 };

 

以上是关于11. Container With Most Water的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode11-Container With Most Water

leetcode 11. Container With Most Water

11. Container With Most Water

11. Container With Most Water

LeetCode11. Container With Most Water 解题报告

11. Container With Most Water