这是一道 困难 的题。
题目来自:https://leetcode.cn/problems/largest-rectangle-in-histogram/
题目
提示:

输入:heights = [2,1,5,6,2,3]
输出:10 解释:最大的矩形为图中红色区域,面积为 10
示例2:

输入: heights = [2,4]
输出: 4

暴力解法
01
解题思路

02
Java 代码实现
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int ans = 0;
for(int i = 0; i < n; i++){
int left = i, right = i, height = heights[i];
while(left - 1 >= 0 && heights[left - 1] >= height){
left--;
}
while(right + 1 < n && heights[right + 1] >= height){
right++;
}
ans = Math.max(ans, (right - left + 1) * height);
}
return ans;
}
}
03
Go 代码实现
func largestRectangleArea(heights []int) int {
n := len(heights)
ans := 0
for i := 0; i < n; i++ {
left, right := i, i
for left - 1 >= 0 && heights[left - 1] >= heights[i] {
left--;
}
for right + 1 < n && heights[right + 1] >= heights[i] {
right++;
}
ans = max(ans, (right - left + 1) * heights[i])
}
return ans
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}
04
复杂度分析

单调栈
01
解题思路

对应到代码里,即 `left = i`, `right = n - 1`,内层寻找左右边界的 `while` 循环就可以省略掉。
class Solution {
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int ans = 0;
for(int i = 0; i < n; i++){
int left = i, right = n - 1, height = heights[i];
ans = Math.max(ans, (right - left + 1) * height);
}
return ans;
}
}

2. 当遇到矮了的柱子就将之前加入的那些更高的柱子以 后进先出 的顺序依次计算答案后删掉。
看到 后进先出,自然而然就想到用 栈 来实现上面思路了。栈中存放的元素是一个数组,数组中存放柱子的宽度和高度。
02
Java 代码实现
class Solution {
private Deque<int[]> stack = new LinkedList<>();
public int largestRectangleArea(int[] heights) {
int n = heights.length;
int ans = 0, width = 0;
// {宽度, 高度}
for(int i = 0; i <= n; i++){
int height = 0;
if(i < n){
height = heights[i];
}
if(stack.isEmpty()){
stack.push(new int[]{1, height});
continue;
}
if(height == stack.peek()[1]){
stack.peek()[0] = stack.peek()[0] + 1;
continue;
}
if(height > stack.peek()[1]){
stack.push(new int[]{1, height});
continue;
}
width = 0;
while(!stack.isEmpty() && height < stack.peek()[1]){
int[] top = stack.pop();
width += top[0];
ans = Math.max(ans, width * top[1]);
}
stack.push(new int[]{width + 1, height});
}
return ans;
}
}
03
Go 代码实现
func largestRectangleArea(heights []int) int {
n := len(heights)
stack := [][]int{}
ans := 0
for i := 0; i <= n; i++ {
height := 0
if i < n {
height = heights[i]
}
if len(stack) == 0 {
stack = append(stack, []int{1, height})
continue
}
if height == stack[len(stack) - 1][1] {
stack[len(stack) - 1][0] = stack[len(stack) - 1][0] + 1
continue
}
if height > stack[len(stack) - 1][1] {
stack = append(stack, []int{1, height})
continue
}
width := 0
for len(stack) > 0 && height < stack[len(stack) - 1][1] {
top := stack[len(stack) - 1]
stack = stack[:len(stack) - 1]
width += top[0]
ans = max(ans, width * top[1])
}
stack = append(stack, []int{width + 1, height})
}
return ans
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}
04
复杂度分析
END


点个
本篇文章来源于微信公众号: i余数
微信扫描下方的二维码阅读本文

Comments NOTHING