LeetCode 11. 盛最多水的容器

我的LeetCode:https://leetcode-cn.com/u/ituring/

我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii

LeetCode 11. 盛最多水的容器

题目

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

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

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

本题相像的是LeetCode 42. 接雨水,可以对比学习;

思路1-贪心算法之双指针遍历

首先明确两个挡板中的最小挡板决定了储水上限,所以贪心或者说动态规划时围绕这个关键点展开;
步骤:

  1. 当前两挡板中的最小值乘以挡板间距就是储水量,每次都移动左右挡板一次,每次移动只有找到比当前最小挡板大的挡板时才停止(若小于,挡板高度不变但间距变小,出水量只会减少);
  2. 以当前两个新挡板的最小值乘以其间距为最大储水量,并对比1更新最大储水量,然后循环进行1之后的操作直至左右挡板相遇;

算法复杂度:

  • 时间复杂度: $ {color{Magenta}{Omicronleft(N ight)}} $
  • 空间复杂度: $ {color{Magenta}{Omicronleft(1 ight)}} $

算法源码示例

package leetcode;

/**
 * @author ZhouJie
 * @date 2019年12月12日 下午9:34:10 
 * @Description: 11. 盛最多水的容器
 *
 */
public class LeetCode_0011 {

}

class Solution_0011 {
	public int maxArea(int[] height) {
		int len = 0;
		if (height == null || (len = height.length) < 2) {
			return 0;
		}
		int i = 0, j = len - 1;
		int max = 0;
		int min = 0;
		while (i < j) {
			// 当前左右挡板中的小值
			min = Math.min(height[i], height[j]);
			// 记录最大储水
			max = Math.max(max, min * (j - i));
			// 向后找到第一个比min大的位置
			while (i < j && height[i] <= min) {
				i++;
			}
			// 向前找到第一个比min大的位置
			while (i < j && height[j] <= min) {
				j--;
			}
		}
		return max;
	}
}

原文地址:https://www.cnblogs.com/izhoujie/p/12727671.html