题目:盛最多水的容器
- 题号:11
- 难度:中等
- https://leetcode-cn.com/problems/container-with-most-water/
给定一个长度为 n 的整数数组 height。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为49。
示例2:
输入:height = [1,1]
输出:1
提示:
- n == height.length
- 2 < = n < = 1 0 5 2 <= n <= 10^5 2<=n<=105
- 0 < = h e i g h t [ i ] < = 1 0 4 0 <= height[i] <= 10^4 0<=height[i]<=104
实现
第一种:利用暴力算法
C# 语言
- 状态:超出时间限制
public class Solution {
public int MaxArea(int[] height) {
int max = int.MinValue;
for (int i = 0; i < height.Length - 1; i++)
{
for (int j = i + 1; j < height.Length; j++)
{
int temp = (j - i)*Math.Min(height[i], height[j]);
if (temp > max)
{
max = temp;
}
}
}
return max;
}
}
第二种:利用双索引的方法
以0-7走到1-7这一步为例,解释为什么放弃0-6这一分支:
用h(i)表示第i条线段的高度,S(ij)表示第i条线段和第j条线段圈起来的面积。
已知 h(0) < h(7),从而S(07) = h(0) * 7。
有S(06) = min(h(0), h(6)) * 6。
当h(0) <= h(6),有S(06) = h(0) * 6;
当h(0) > h(6),有S(06) = h(6) * 6,S(06) < h(0) * 6。
由此可知,S(06)必然小于S(07)。
把每一棵子树按照同样的方法分析,很容易可以知道,双索引法走的路径包含了最大面积。
C# 语言
public class Solution
{
public int MaxArea(int[] height)
{
int i = 0, j = height.Length - 1;
int max = int.MinValue;
while (i < j)
{
int temp = (j - i) * Math.Min(height[i], height[j]);
if (temp > max)
{
max = temp;
}
if (height[i] < height[j])
{
i++;
}
else
{
j--;
}
}
return max;
}
}
Python 语言
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
i, j = 0, len(height) - 1
m = 0
while i < j:
temp = (j - i) * min(height[i], height[j])
if temp > m:
m = temp
if height[i] < height[j]:
i += 1
else:
j -= 1
return m