题目描述

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

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

011 盛最多水的容器 - 图1

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

示例:

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

题解

暴力法

暴力法的实现比较简单,这里就不解释了。

  1. public int MaxArea(int[] height)
  2. {
  3. var maxArea = 0;
  4. for (var i = 0; i < height.Length; i++)
  5. for (var j = i + 1; j < height.Length; j++)
  6. maxArea = Math.Max(maxArea, Math.Min(height[i], height[j]) * (j - i));
  7. return maxArea;
  8. }

双指针法

该方法的思路是线段间的面积受较短那条长度的限制,同时两线段距离越远面积越大。

使用两个指针,一个放在开始,一个放在末尾。每次移动时将指向较短那条的指针向指向较长那条移动一步。

  1. public int MaxArea(int[] height)
  2. {
  3. var maxArea = 0;
  4. for (int i = 0, j = height.Length - 1; i < j;)
  5. {
  6. var w = j - i;
  7. var h = Math.Min(height[i], height[j]);
  8. var area = w * h;
  9. if (area > maxArea) maxArea = area;
  10. if (height[i] < height[j]) i++;
  11. else j--;
  12. }
  13. return maxArea;
  14. }