我的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更新最大储水量,然后循环进行1之后的操作直至左右挡板相遇;
算法复杂度:
- 时间复杂度: $ {\color{Magenta}{\Omicron\left(N\right)}} $
- 空间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $
算法源码示例
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;
}
}
来源:oschina
链接:https://my.oschina.net/u/4312361/blog/3274812