在一個由 '0'
和 '1'
組成的二維矩陣內,找到只包含 '1'
的最大正方形,並返回其面積。算法
動態規劃只能應用於有最優 子結構
的問題。最優子結構的意思是局部最優解能決定全局最優解
(對有些問題這個要求並不能徹底知足,故有時須要引入必定的近似)。數組
簡單地說,問題可以分解成子問題來解決
。markdown
通俗一點來說,動態規劃和其它遍歷算法(如深/廣度優先搜索)都是將原問題拆成多個子問題而後求解
,他們之間最本質的區別是,動態規劃保存子問題的解,避免重複計算
。oop
解決動態規劃問題的關鍵是找到狀態轉移方程
,這樣咱們能夠通計算和儲存子問題的解來求解最終問題
。spa
同時,咱們也能夠對動態規劃進行空間壓縮
,起到節省空間消耗的效果。code
在一些狀況下,動態規劃能夠當作是帶有狀態記錄(memoization)的優先搜索
。orm
動態規劃是自下而上的
,即先解決子問題,再解決父問題;leetcode
而用帶有狀態記錄的優先搜索
是自上而下
的,即從父問題搜索到子問題,若重複搜索到同一個子問題則進行狀態記錄,防止重複計算。get
若是題目需求的是最終狀態,那麼使用動態搜索比較方便;it
若是題目須要輸出全部的路徑,那麼使用帶有狀態記錄的優先搜索會比較方便。
一、定義一個二維 dp 數組,其中dp[i][j] 表示以 (i, j) 爲右下角的正方形, dp[i][j] = k,爲邊長爲k的正方形
二、假設dp[i][j]爲k 正上方dp[i-1][j] 斜上方dp[i-1][j-1] 左方dp[i][j-1],都得爲最小值k-1,
三、那麼dp[i][j]的取值 爲matrix[i][j] === 1時候,正上方dp[i-1][j] 斜上方dp[i-1][j-1] 左方dp[i][j-1] 的最小值 加上 此處matrix[i][j] === 1 的值
三、則 (i, j) 位置必定且最大能夠構成一個邊長爲 k 的正方形。
四、狀態轉移方程dp[i][j] = Math.min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;
/**
* @param {character[][]} matrix
* @return {number}
*/
var maximalSquare = function(matrix) {
let n = matrix.length, m = matrix[0].length;
let dp = Array.from({length:n}, ()=> new Array(m).fill(0));
let max = 0;
for(let i = 0; i < n; i++) {
if(matrix[i][0] === '1') {
dp[i][0] = 1;
max = 1;
}
}
for(let i = 0; i < m; i++) {
if(matrix[0][i] === '1') {
dp[0][i] = 1;
max = 1;
}
}
for(let i = 1; i < n; i++) {
for(let j = 1; j < m; j++) {
if(matrix[i][j] === '1'){
dp[i][j] = Math.min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;
max = Math.max(dp[i][j], max);
}
}
}
return max * max;
};
複製代碼