問題描述:
題目鏈接: 221 Maximal Square
問題找解決的是給出一個M*N的矩陣, 只有'1', '0',兩種元素; 需要你從中找出 由'1'組成的最大正方形。恩, 就是這樣。
我們看到, 這道題目的標簽還是DP, 那么問題的關鍵就是要找到一個符合判斷是否為正方形的遞推式。
老套路, 先看基本型, 對於一個2*2的正方形,對於右下角的元素(1,1)而言, 他的上(0,1), 左(1,0), 左上(0,0)三個元素應該都是'1',
如此才能夠組成一個合規的正方形; 那么如果是一個3*3呢, 首先他必然是一個2*2, 然后左加一列,上添一行,就由一個2*2成了一個3*3型,所以, 對於在矩陣中的
任意一個點'1'只要不斷匹配他的左邊列和上邊行都是‘1’, 並計數后再往外匹配一層,知道出現'0'或者到達邊界即可, 然后從每個點中選出匹配到的最大層數, done!
基本套路就是如此, 但是每個點都走一遍就是M*N個點, 后每個點都再外面一層逐個匹配, 時間復雜度消耗不起,O(M^2*N^2), 一般考慮M*N,直接近似4次方的復雜度,
肯定不可取。既然從后往前不靠譜, 那我們從前往后推又如何呢?
除去邊界(即第一行與第一列),對於任意一個matrix[i][i],他所處的方形應該前一層決定:左邊(matrix[i][j-1]), 上邊(matrix[i-1][j]),左上(matrix[i-1][j-1])決定,
同樣的, 我們也需要一個結果矩陣 ret[M][N] 記錄每個對應點所處的方形層數。
再看最基本型:對於在matrix[1][1]出的點, 他的左上外層全為'1', 故這個點在ret[1][1]就+1,結果記為2,
即:if: (top != '0', left!='0', top_left!='0')
then: ret[i][j] = matrix[i][j]+1;
在考慮到這一步的時候, 覺得已經ok了, 立刻在頁面寫好代碼提交, 結果卻是一個大大的Wrong Answer! 當下覺得沒錯啊, 對於每個點是不是處於方形都做了
判斷, 而且判定了之后還把層數+1嘞,於是輸出結果矩陣一看:
很明顯, 對於層數計算, 並沒有獲取前一層的都處於的方形層數, 要知道,假設在[i][j]為止是屬於3*3的方形, 那么必然有點[i-1][j],[i][j-1], [i-1][j-1]這3個都至少屬於
2*2的方形, 可能用圖示更清楚:
left:
top:
left_top:
所以上面的情形如果在遞推產生的ret矩陣中就是這個樣子:
left:
top:
left_top:
所以, 更正后的遞推式應該是:
再次提交, Accepted!
最后只解決的代碼:
另外, 還有一道相近的(鏈接在這里), 這次不定形狀了, 你是一行, 還是正方形沒有限制了, 難度也提升為Hard級別,
但核心思想肯定沒變, 各位額可以嘗試下, 此題明后日貼個人解決思路。
最后還是老話, 本人貼上來的解法和思路僅作是記錄,或者還可以向各位看官交流學習,有幫助就好。