相似題目:01矩陣裏找面積最大的全1方矩陣
解法:動態規劃
if num[i][j] == 0:
dp[i][j] = 0
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-1], dp[i-1][j-1]) + 1
本題:01矩陣裏找面積最大的全1矩陣,不再限制於方陣
解法:動態規劃
思路:轉換成找面積最大的直方圖問題,時間O(mn),但易超時
這樣就轉化成了找面積最大的直方圖問題,參考這份鏈接:https://www.cnblogs.com/mickole/articles/3654280.html
兩種方法,例如對於下圖,求最大面積
方法一:暴力枚舉:遍歷每一個數字,計算其左右不低於他的長度,得到面積 ,並使用max一直保存,O(nn)
方法二:單調棧:
以H[i]爲高的矩形向左右擴展,找到能夠到達的最遠距離,即找到左右邊界第一個小於H[ i ]的位置, 實際上就是一道單調棧的問題,用一個棧來維護一個單調遞增的序列,如果棧中的某個元素比當前的數值的小,那麼該元素之後的元素肯定是用不到了,所以就可以直接丟出棧, 並將該值加入棧中,遍歷一遍,用ans記錄最大值即可
https://blog.csdn.net/qq_43328040/article/details/90735071
一個線性算法是用堆棧來保存當前可能的矩形(高度和起始位置)。從左到右掃描,對一個元素,如果
a)大於棧頂元素, push;
b)小於的話,pop所有的大於它的元素,計算面積,更新最大值。這時如果堆棧空,push一個新的元素,高度等於當前元素,起始位置爲0;否則,push當前元素高度和棧頂的起始位置。
再仔細解釋一下上述流程:
0.對於13223這個數組,首先對於空棧,我們壓入第一個元素以及位置,stack=[(1,0)]
1.然後因爲3大於棧頂,繼續壓入,stack=[(1,0), (3,1)]
2.接下來2小於棧頂,彈出棧頂並計算ans = 3*(2-1) = 3,然後壓入(2,1),注意此時不是壓入(2,2),stack=[(1,0), (2,1)]
3.當前2等於棧頂,stack=[(1,0), (2,1)]
4.3大於棧頂,繼續壓入,stack=[(1,0), (2,1), (3,4)]
5.全部元素入棧完畢,開始逐個元素pop並計算ans,首先pop(3,4),ans = 3*(5-4) = 3,stack=[(1,0), (212)]
5.pop(2,1),ans = 2*(5-1) = 8,stack=[(1,0)]
5.pop(1,0),ans = 1*(5-0) = 5,stack=[],算法結束,使用線性時間