11. 盛最多水的容器
链接:https://leetcode-cn.com/problems/container-with-most-water/
题目描述见链接内容。
解法1:暴力法
二话不说,暴力开干。分别以每两个坐标作为起始点,画出矩形,比较大小:
var maxArea = function (height) {
const len = height.length;
let result = 0;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
result = Math.max((j - i) * Math.min(height[i], height[j]), result);
}
}
return result;
};
- 时间复杂度: O ( N 2 ) {O(N^2)} O(N2)
- 空间复杂度: O ( 1 ) {O(1)} O(1)
- 执行用时:果不其然,超时了
解法2:双指针
看完题解之后,发现自己没有过多的自己纠缠是正确的,因为凭自己的智商,根本想不到使用双指针的。看完题解后,说真的,难吗?代码写的很轻松就通过了,但是就是想不到
如果智商够,那么没问题了,如果智商不够,那么只能多做题做扩展思路,在遇到类似的问题,武器库里能多一种使用双指针不断缩小问题规模的武器
声明两个指针,一个在开始位置,一个在结束位置,可以计算出当前可以盛水的容量,然后判断开始位置和结束位置哪个比较小,如果开始位置较小,那么开始指针向后移动,如果结束位置较小,那么结束指针向前移动
也就是说,总是移动数字较小的那个指针,为什么呢?直观的理解,首先无论移动哪个指针,两个指针的间距一定是变小了的,如果移动较大的指针,最终的结果一定小于之前的容积(因为计算容积是的Y轴的值取的是较小者),所以也就意味着这时候较小的指针的位置就被放弃了,因为无论如何都不会再变大了,所以需要移动它
数学证明也不难,可以参考官方题解的证明
代码实现:
var maxArea = function (height) {
let start = 0,
end = height.length - 1,
result = 0;
while (start < end) {
result = Math.max(result, Math.min(height[start], height[end]) * (end - start));
// 移动较小的指针
if (height[start] < height[end]) {
start += 1;
} else {
end -= 1;
}
}
return result;
};
- 时间复杂度: O ( N ) {O(N)} O(N)
- 空间复杂度: O ( 1 ) {O(1)} O(1)
- 执行用时:100ms, 在所有JavaScript提交中击败了74.69%的用户,内存消耗:46.9MB,在所有JavaScript提交中击败了60.91%的用户