Leetcode算法Java全解答–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
想法
-
暴力破解
2层循环,计算面积时间复杂度:O(n^2)
空间复杂度:O(1)
-
双指针法
一个指针指向第一个数据一个指针指向最后一个数据
算出面积,与已有面积对比
将短的那条往长的那条靠拢
返回结果
时间复杂度:O(n)
空间复杂度:O(1)
结果
超过23%的测试案例
超过69%的测试案例
总结
没有想到使用双指针法,感觉这样子算起来数据不对
代码
我的答案
public class Solution011 {
/**************************************
* 题目
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
**************************************/
/**************************************
*
* 想法:
* 1. 暴力破解
* 2层循环,计算面积
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* 2.双指针法
* 一个指针指向第一个数据
* 一个指针指向最后一个数据
* 算出面积,与已有面积对比
* 将短的那条往长的那条靠拢
* 返回结果
*
* 时间复杂度:O(n)
* 空间复杂度:O(1)
* 我的做法
* 超过23%的测试案例
*
* 代码执行过程:
*
* 总结:
*
* ***********************************/
public int maxArea(int[] height) {
int maxVal = 0;
int left = 0;
int right = height.length - 1;
while (left < right) {
int dif = right - left;
int leftVal = height[left];
int rightVal = height[right];
int value = calcArea(leftVal, rightVal, dif);
maxVal = Math.max(maxVal, value);
if (leftVal < rightVal) {
left++;
} else {
right--;
}
}
return maxVal;
}
/**
* 暴力破解
* 超过23%的测试案例
*
* @param height 数组
* @return
*/
public int maxAreaByBrute(int[] height) {
int maxVal = 0;
for (int i = 0; i < height.length; i++) {
for (int j = i + 1; j < height.length; j++) {
int dif = j - i;
int value = calcArea(height[i], height[j], dif);
maxVal = Math.max(maxVal, value);
}
}
return maxVal;
}
private static int calcArea(int i, int j, int dif) {
int min = Math.min(i, j);
return min * dif;
}
}
大佬们的答案
/**************************************
* 比我好的答案 better
* ***********************************/
public int better(int[] height) {
// 声明变量
int left = 0, right = height.length - 1, max = 0;
while (left < right) {
// 算出结果
max = Math.max(Math.min(height[left], height[right]) * (right - left), max);
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}
return max;
}
测试用例
@Test
public void test011() {
// 创建测试案例
int[] arr1 = new int[] { 1, 8, 6, 2, 5, 4, 8, 3, 7 };
// 测试案例期望值
int expResult1 = 49;
// 执行方法
Solution011 solution011 = new Solution011();
int result1 = solution011.maxArea(arr1);
// 判断期望值与实际值
Assert.assertEquals(expResult1, result1);
}
其他
代码托管码云地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git
查看其他内容可以点击专栏或者我的博客哈:https://blog.csdn.net/cmqwan
“大佬们的答案” 标签来自leetcode,侵权请联系我进行删改
如有疑问请联系,联系方式:QQ3060507060