看到题目的第一感觉是动态规划,于是乎开始苦思冥想了一波。无果
然后尝试用笨法做(升级版暴力)
从两侧向内包围。每次选择较小的一边向内收紧。
保留一个最大的面积res,最终通过。
代码如下
/**
* @param {number[]} height
* @return {number}
*/
//动态规划||双指针 ✅
var maxArea = function(height) {
let cur1 = 0;
let cur2 = height.length-1;
let res = 0;
for(let i=0;i<height.length;i++){
let area = Math.min(height[cur1],height[cur2])*(cur2-cur1);
console.log(cur1,cur2,area)
if(area>res){
res = area;
}
if(height[cur1]>height[cur2]){
cur2--;
}else{
cur1++;
}
}
return res;
};
可惜的是,内存和用时都很差,看一波题解进行优化:
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function (height) {
let res = 0, i = 0, j = height.length - 1;
while (i < j) {
res = Math.max(res, Math.min(height[i], height[j]) * (j - i))
if (height[i] < height[j]) {
i++
} else {
j--
}
}
return res
}
完美。
时间复杂度On
空间复杂度O1
关于为什么可以用这种双指针解法进行,为什么要向内移动高度较小的一方
:个人理解如下
1、首先决定盛水面积多少的是 高度较小的一方,所以当高度缩进的时候,移动较高的一边面积一定会减小,只有移动较小边,面积才会增大。
2、从两侧夹紧包含了全部情况的,符合正常逻辑的同时还避免了暴力法的不必要操作。