题目
思路
看到题目的第一眼,就觉得,这是个动态规划题,公式也很明显:
设开始下标为s,结束下标为e,会有以下概念:
设C(s, e)为s到e的面积,其值为(e - s) * Math.min(height[e], height[s])
则M(s, e) = Math.max(M(s + 1, e), M(s, e - 1), C(s, e))
代码写起来也比较简单
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let record = new Map();
function getVal(s, e) {
if (s >= e) return 0;
let key = `${s},${e}`;
let val = 0;
if (record.has(key)) {
val = record.get(key);
} else {
val = (e - s) * Math.min(height[s], height[e]);
val = Math.max(getVal(s + 1, e), getVal(s, e - 1), val);
record.set(key, val);
}
return val;
}
return getVal(0, height.length - 1);
};
但很遗憾,提交没能通过,错误原因如下:
原来是超内存了,想了一下,毕竟是O(n2)的复杂度,中间生成的数据,也会是n2的量,还是挺大的,所以挂掉还是挺正常的。
仔细思考一下,发现题目中好像有些条件还没有利用上,即存在短板效应,如果两个数a和b,取的是较小的那个值进行计算面积,另外的一个值再大也没用。
来一步一步分析:
- 按照动态规划,我们需要比较M(s + 1, e), M(s, e - 1), C(s, e)三者的大小
- 其中M(s + 1, e), M(s, e - 1)会出现相当多重复的计算,我们中间是用record存储了,没什么问题,
- M(s + 1, e)相比M(s, e - 1)会多出以下计算:C(s + 1, e), C(s + 2, e),C(s + 3, e)...C(e - 1, e)
- 但如果height[s] > height[e],这些计算好像都没有必要去做,因为短板效应,会导致C(s, e)肯定是大于等于这些值的。那么在这种情况下,M(s + 1, e)是没必要计算的【重复的计算M(s, e - 1)中有了,多余的计算又是没必要的】
- 同理如果height[s] <= height[e],也会有一些计算,是没必要的
修改一下代码:
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let record = new Map();
function getVal(s, e) {
if (s >= e) return 0;
let key = `${s},${e}`;
let val = 0;
if (record.has(key)) {
val = record.get(key);
} else {
val = (e - s) * Math.min(height[s], height[e]);
// 选择性的进行计算
if (height[s] > height[e]) {
val = Math.max(getVal(s, e - 1), val);
} else{
val = Math.max(getVal(s + 1, e), val);
}
record.set(key, val);
}
return val;
}
return getVal(0, height.length - 1);
};
再去提交一下,就过了:
虽然过了,但这击败5%,实在不太好看,再整理一下,上面的代码,其实不就是个双指针吗,也没必要存储中间的数据,再改一下:
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let max = 0;
let s = 0, e = height.length - 1;
while (s < e) {
max = Math.max(max, (e - s) * Math.min(height[s], height[e]));
if (height[s] < height[e]) {
s++;
} else {
e--;
}
}
return max;
};
结果:
yysy,js的执行时间不太稳定,同样的代码每次排名都不一样,好不容易才跑到一个比较好看的数据😄