11. 盛水最多的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解法1
思路: 枚举(暴力解决呗)
left bar x, right bar y ,(x - y) * height_diff 时间复杂度o(n^2)
结果: 击败了28.40%的用户, 时间复杂度是O(n^2),速度慢是肯定的了,内存消耗还行
以后写算法写代码,实在没思路就暴力解决好了,暴力解决ok了,再来一步一步优化
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let max = 0;
for(let i = 0; i < height.length - 1; i++) {
for(let j = i + 1; j < height.length; j++) {
let area = ( j - i ) * Math.min(height[i], height[j]);
max = Math.max(max, area);
}
}
return max;
};
解法2
思路: 棒子大法 左右边界同时向中间收敛 左右夹逼 左右边界选最两边,它的宽度是最宽的,高度不一定最高,但是这种情况下,往中间靠拢收敛的时候棒子的高度如果没有外面的棒子高的时候就不用再看了,因为里面的棒子高度都不及我的话,宽度也肯定不及我,于是面积就小,直接可以忽略…最后当左右棒子相遇的时候(i= j)的时候得出结果….
没有嵌套循环 时间复杂度 肯定是o(n)
结果: 64ms 打败92.61%
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function(height) {
let max = 0
for(let i = 0, j = height.length -1; i < j;) {
// 谁更小 谁就挪
let minHeight = height[i] < height[j] ? height[i++] : height[j--]
let area = (j - i + 1) * minHeight
max = Math.max(max, area)
}
return max
};