問題描述
對於一個 m * n 的矩陣,每項元素爲 0 或 1.
問題1
求該矩陣中的最大子矩陣,子矩陣可以爲長方形,但是子矩陣內的各項元素均爲 1。
解決1
針對這個問題,可以枚舉子矩陣的左右邊界,複雜度爲 O(n^2)。針對該邊界內的m行,從上到下掃一次,每行的和,如果爲左右邊界之差,那麼該行的每項元素都爲 1 。從上往下掃各行,求得最長連續地滿足要求的行數。從而可以求得子矩陣的面積。
求特定邊界內每行的面積,如何求?L[i][j] 爲 A[i][0] ~ A[i][j] 的元素之和。根據 L[i][j] 就可以方便的求得 特定行的區間面積。比如求 A[i][k1] ~ A[i][k2] 的和,那麼就是 L[i][k2] - L[i][k1-1]。
因此總體的複雜度爲 O(n^2) * O(m) 即 O(m*n^2),其中 m爲從上往下掃描的時間。
問題2
針對問題1,如果該子矩陣爲正方形,如何求解?
解決2
設定一個輔助數組 C[i][j] 對應着一個數值對(l, h),其中 l 是指從 A[i][j] 開始往左,且包含 1,其最大長度; h 是指 從A[i][j] 開始往上,且包含 1,其最大長度。
p[i][j] 爲以 A[i][j]元素爲右下邊界的最大正方形矩陣的長度。
於是 p[i+1][j+1] = min( p[i][j]+1, c[i+1][j+1].l , c[i+1][j+1].h)
時間複雜度爲O(mn),空間複雜度爲O(mn)。
解決。
PS 原題鏈接:Elements of Programming Interviews, P120