From b22425c859269c5862149a8f736bcf0c3e5e00eb Mon Sep 17 00:00:00 2001 From: Relsola Date: Mon, 25 Dec 2023 22:55:12 +0800 Subject: [PATCH] =?UTF-8?q?Update=200084.=E6=9F=B1=E7=8A=B6=E5=9B=BE?= =?UTF-8?q?=E4=B8=AD=E6=9C=80=E5=A4=A7=E7=9A=84=E7=9F=A9=E5=BD=A2=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=90=8D=E9=94=99=E8=AF=AF=E4=BF=AE=E5=A4=8D=E5=92=8C?= =?UTF-8?q?=E5=8F=AF=E8=AF=BB=E6=80=A7=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0084.柱状图中最大的矩形.md | 66 ++++++++++++-------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index 97dab4f3..b836705a 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -515,27 +515,31 @@ func largestRectangleArea(heights []int) int { var largestRectangleArea = function(heights) { const len = heights.length; const minLeftIndex = new Array(len); - const maxRigthIndex = new Array(len); + const maxRightIndex = new Array(len); // 记录每个柱子 左边第一个小于该柱子的下标 minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环 for(let i = 1; i < len; i++) { let t = i - 1; // 这里不是用if,而是不断向左寻找的过程 - while(t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t]; + while (t >= 0 && heights[t] >= heights[i]) { + t = minLeftIndex[t]; + } minLeftIndex[i] = t; } // 记录每个柱子 右边第一个小于该柱子的下标 - maxRigthIndex[len - 1] = len; // 注意这里初始化,防止下面while死循环 + maxRightIndex[len - 1] = len; // 注意这里初始化,防止下面while死循环 for(let i = len - 2; i >= 0; i--){ let t = i + 1; // 这里不是用if,而是不断向右寻找的过程 - while(t < len && heights[t] >= heights[i]) t = maxRigthIndex[t]; - maxRigthIndex[i] = t; + while (t <= n && heights[t] > heights[i]) { + t = maxRightIndex[t]; + } + maxRightIndex[i] = t; } // 求和 let maxArea = 0; for(let i = 0; i < len; i++){ - let sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1); + let sum = heights[i] * (maxRightIndex[i] - minLeftIndex[i] - 1); maxArea = Math.max(maxArea , sum); } return maxArea; @@ -543,27 +547,37 @@ var largestRectangleArea = function(heights) { //单调栈 var largestRectangleArea = function(heights) { - let maxArea = 0; - const stack = []; - heights = [0,...heights,0]; // 数组头部加入元素0 数组尾部加入元素0 - for(let i = 0; i < heights.length; i++){ - if(heights[i] > heights[stack[stack.length-1]]){ // 情况三 - stack.push(i); - } else if(heights[i] === heights[stack[stack.length-1]]){ // 情况二 - stack.pop(); // 这个可以加,可以不加,效果一样,思路不同 - stack.push(i); - } else { // 情况一 - while(heights[i] < heights[stack[stack.length-1]]){// 当前bar比栈顶bar矮 - const stackTopIndex = stack.pop();// 栈顶元素出栈,并保存栈顶bar的索引 - let w = i - stack[stack.length -1] - 1; - let h = heights[stackTopIndex] + let maxArea = 0; + const stack = [0]; + heights.push(0); + const n = heights.length; + + for (let i = 1; i < n; i++) { + let top = stack.at(-1); + // 情况三 + if (heights[top] < heights[i]) { + stack.push(i); + } + // 情况二 + if (heights[top] === heights[i]) { + stack.pop(); // 这个可以加,可以不加,效果一样,思路不同 + stack.push(i); + } + // 情况一 + if (heights[top] > heights[i]) { + while (stack.length > 0 && heights[top] > heights[i]) { + // 栈顶元素出栈,并保存栈顶bar的索引 + const h = heights[stack.pop()]; + const left = stack.at(-1) ?? -1; + const w = i - left - 1; // 计算面积,并取最大面积 - maxArea = Math.max(maxArea, w * h); - } - stack.push(i);// 当前bar比栈顶bar高了,入栈 - } - } - return maxArea; + maxArea = Math.max(maxArea, w * h); + top = stack.at(-1); + } + stack.push(i); + } + } + return maxArea; }; //单调栈 简洁