leetcode 85 最大矩形(動態規劃,棧)

2021-09-24 09:33:32 字數 4122 閱讀 3908

給定乙個僅包含 0 和 1 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。

示例:

輸入:

[ ["1","0","1","0","0"],

["1","0","1","1","1"],

["1","1","1","1","1"],

["1","0","0","1","0"]

]輸出: 6

1 使用柱狀圖的優化暴力方法

設定二維陣列dpdp[i][j]表示以該座標結束的矩形的最大可能寬度。

dp[i][j] = dp[i][j-1] + 1 if matrix[i][j] == '1'
一旦我們知道每個點對應的最大寬度,就可以以線性時間內計算出以該點為右下角的最大矩形。我們從該位置第i行往上遍歷該列,可以得到從初始點(i,j)到當前點矩形的最大寬度,就是我們遇到的每個最大寬度d[k][j]的最小值。

我們定義

currentwidth = max(currentwidth, dp[i][k])

currentarea = currentwidth * (i - k + 1)

maxarea = max(maxarea, currentarea)

對每個點重複這一過程,就可以得到全域性最大。

注意,我們預計算最大寬度的方法事實上將輸入轉化成了一系列的柱狀圖,每一欄是乙個新的柱狀圖。我們在針對每個柱狀圖計算最大面積。

於是,上述方法本質上是84 - 柱狀圖中最大的矩形題中優化暴力演算法的復用。

複雜度分析

時間複雜度:o(m

2n)o(m^2n)

o(m2n)

空間複雜度:o(m

n)o(mn)

o(mn

)m,n為輸入矩陣的行列數

2 動態規劃-每個點的最大高度

想象乙個演算法,對於每個點我們會通過以下步驟計算乙個矩形:

不斷向上方遍歷,直到遇到「0」,以此找到矩形的最大高度。

向左右兩邊擴充套件,直到無法容納矩形最大高度。

例如,找到黃色點對應的矩形:

我們知道,最大矩形必為用這種方式構建的矩形之一。

給定乙個最大矩形,其高為h, 左邊界l,右邊界r,在矩形的底邊,區間[l, r]內必然存在一點,其上連續1的個數(高度)<=h。若該點存在,則由於邊界內的高度必能容納h,以上述方法定義的矩形會向上延伸到高度h,再左右擴充套件到邊界[l, r],於是該矩形就是最大矩形。

若不存在這樣的點,則由於[l, r]內所有的高度均大於h,可以通過延伸高度來生成更大的矩形,因此該矩形不可能最大。

綜上,對於每個點,只需要計算hl,和r- 矩形的高,左邊界和右邊界。

演算法

給定一行matrix[i],我們通過定義三個陣列heightleft,和right來記錄每個點的hl,和rheight[j]對應matrix[i][j]的高,以此類推。

問題轉化為如何更新每個陣列。

height:

這個比較容易。h的定義是從該點出發連續的1的個數。

row[j] = row[j - 1] + 1 if row[j] == '1'
只需要一點改動即可:

new_height[j] = old_height[j] + 1 if row[j] == '1' else 0
left:考慮哪些因素會導致矩形左邊界的改變。由於當前行之上的全部0已經考慮在當前版本的left中,唯一能影響left就是在當前行遇到0

因此我們可以定義:

new_left[j] = max(old_left[j], cur_left)

cur_left是我們遇到的最右邊的0的序號加1。當我們將矩形向左 「擴充套件」 ,我們知道,不能超過該點,否則會遇到0。

right:

我們可以沿用left的思路,定義:

new_right[j] = min(old_right[j], cur_right)
cur_right是我們遇到的最左邊的0的序號。簡便起見,我們不把cur_right減去1 (就像我們給cur_left加上1那樣) ,這樣我們就可以用height[j] * (right[j] - left[j])而非height[j] * (right[j] + 1 - left[j])來計算矩形面積。

這意味著, 嚴格地說 ,矩形的底邊由半開半閉區間[l, r)決定,而非閉區間[l, r],且right比右邊界大1。儘管不這樣做演算法也可以正確執行,但這樣會讓計算看起來更簡潔。

注意,為了正確的記錄cur_right,我們需要從右向左迭代。因此,更新right時需要從右向左。

一旦leftright,和height陣列能夠正確更新,我們就只需要計算每個矩形的面積。

由於我們知道矩形j的邊界和高,可以簡單地用height[j] * (right[j] - left[j])來計算面積,若j的面積 大於max_area,則更新之。

複雜度分析

時間複雜度:o(m

n)o(mn)

o(mn

)空間複雜度:o(n

)o(n)

o(n)

m,n為輸入矩陣的行列數

/*

* 動態規劃

* 時間複雜度o(mn) 空間複雜度o(n)

* m,n為陣列行列數

*/class

solutionii

// 更新left

for(

int j =

0; j < cols;

++j)

}// 更新right

for(

int j = cols-

1; j >=0;

--j)

}// 更新最大面積

LeetCode 85 最大矩形

給定乙個僅包含 0 和 1 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。示例 輸入 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 輸出 6此題和上一題的擴充套件,此題給的二維矩陣的每一行向上都形成了乙個直方圖,所以二維矩陣有多少行,就有多少個直方圖...

leetcode85 最大矩形

1.轉換成直方圖的做法 參考 利用leetcode84中的方法來做 首先要將給定的01矩陣轉換成84中的直方圖的樣子。每一行都對應乙個直方圖,且下一行直方圖是由上一行直方圖計算得到的。如果是0,則當前直方圖高為0,如果是1,則當前直方圖高度是上一層對應位置高度 1 1 0 1 0 0 1,0 1,0...

LeetCode 85 最大矩形

給定乙個僅包含 0 和 1 的二維二進位制矩陣,找出只包含 1 的最大矩形,並返回其面積。示例 輸入 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 輸出 6這一題的演算法本質上和84題largest rectangle in histogram一樣,對每一列都求出每...