菜雞每日一題系列打卡84天
每天一道算法題目
小夥伴們一起留言打卡
堅持就是勝利,我們一起努力!
題目描述(引自LeetCode)
給定n個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度爲1。
求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
以上是柱狀圖的示例,其中每個柱子的寬度爲1,給定的高度爲[2,1,5,6,2,3]。
圖中陰影部分爲所能勾勒出的最大矩形面積,其面積爲10個單位。
示例:
輸入: [2,1,5,6,2,3]
輸出: 10
題目分析
這道題目最容易想到的是暴力法,通過雙重for循環枚舉高度(或者寬度),從而得到柱狀圖中最大的矩形,但基於暴力搜索的時間複雜度爲O(n^2),我們需要對此進行優化。
這時候就需要用到一種經典的數據結構——單調棧,其實就是一種棧,只不過其中的元素是有序的。值得注意的是,通過單調棧維護小於柱子i的高度值,需要注意棧爲空時設置哨兵。
話不多說,上代碼!
代碼實現
class Solution {
public int largestRectangleArea(int[] heights) {
if (heights == null || heights.length == 0) return 0;
int length = heights.length;
int[] left = new int[length];
int[] right = new int[length];
Arrays.fill(right, length);
Stack<Integer> stack = new Stack<Integer>();
for (int i = 0; i < length; i++) {
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) right[stack.pop()] = i;
left[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(i);
}
int result = 0;
for (int i = 0; i < length; i++) {
int tmp = (right[i] - left[i] - 1) * heights[i];
if (tmp > result) result = tmp;
}
return result;
}
}
代碼分析
對代碼進行分析,程序採用了單調棧進行實現,每一個位置只會入棧一次(在枚舉到它時),並且最多出棧一次,因此單調棧的時間複雜度爲O(n);而就空間而言,採用了額外的數組空間和單調棧空間,空間複雜度爲O(n)。
執行結果
學習 | 工作 | 分享
????長按關注“有理想的菜雞”
只有你想不到,沒有你學不到