(双指针)leetcode-11

77 阅读1分钟

盛最多水的容器

题目

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

  • n==height.lengthn == height.length
  • 2<=n<=1052 <= n <= 10^5
  • 0<=height[i]<=1040 <= height[i] <= 10^4

思路

  • 这道题如果使用暴力的话,思路简单,依次对比每两段,较小的那一段长度*两段间的距离就是它们的盛水量,但是时间复杂度达到 O(n2)O(n^2),不满足题目要求。
  • 于是没了什么思路,看了题解才发现可以用双指针
  • 由于可容纳水的高度由两板中的短板决定,因此可得如下面积公式 :
  • S(i,j)=min(h[i],h[j])×(ji)S(i, j) = min(h[i], h[j]) × (j - i)
  • l=0r=height.lengthl=0,r=height.length 从两侧向内,收缩较短的那一边,然后计算大小,取得max值
  • 为什么是这样呢?原因在于:
  • 向内移动短板,水槽的短板min(h[i],h[j])min(h[i], h[j])可能变大,因此下个水槽的面积可能增大 。
  • 向内移动长板,水槽的短板 min(h[i],h[j])min(h[i], h[j])不变或变小,因此下个水槽的面积一定变小 。

代码

 class Solution {
    public int maxArea(int[] height) {
        int l = 0;
        int r = height.length-1;
        int max = 0 ;
        while(l<r){
           max = height[l]<height[r]? Math.max(max,(r-l)*height[l++]): Math.max(max,(r-l)*height[r--]);
        }
        return max;
    }
}