11. 盛最多水的容器

11. 盛最多水的容器 - 力扣(LeetCode)

二刷

class Solution {
public:
  int maxArea(vector<int>& height) {
    int l = 0, r = height.size() - 1;
    int Result = 0;
    while (l != r) {
      // You can in fact see the thinking process here. The effective height is
      // always the MINIMUM of two heights-
      int EffectiveHeight = min(height[l], height[r]);
      int Width = r - l;
      Result = max(Result, EffectiveHeight * Width);
      // And that's why we always choose the shortest one to advance.
      if (height[l] < height[r])
        ++l;
      else
        --r;
    }
    return Result;
  }
};

这道题其实非常简单,本质上是一个贪心算法,它的思路用四个字就可以概括——「短板效应」。事实上你从我们对于体积的计算过程当中也可以看得出来,我们每次的实际体积都受最短的那块板的影响。也正因如此,我们每次都寄希望于移动最短的那块板所对应的 index,以求找到可能的长板。

二刷

class Solution {
public:
  int maxArea(vector<int>& height) {
    int MaxArea = 0;
    int L = 0, R = height.size() - 1;
    while (L != R) {
      int LH = height[L];
      int RH = height[R];
      int Area = (R - L) * min(LH, RH);
      MaxArea = std::max(MaxArea, Area);
      // Use while-loop to fast-forward pointers. Not really needed but this
      // coincidentally looks exactly like how we do in QuickSort.
      if (LH < RH)
        while (L != R && height[++L] < LH);
      else
        while (L != R && height[--R] < RH);
    }
    return MaxArea;
  }
};

跟一刷没什么差别,但是我这里在外循环末尾直接把指针快进了。虽然快进操作不是强制的,但按理来说常数能小一点。这其实跟快排(快速选择)的那个双循环是同一个东西,而且写法看上去也几乎一致。