二维/矩阵类DP
矩阵类的题目能用DFS解答的都要想到memoization来优化,Tree则不能用memo优化
Maximal Square
典型的矩阵类DP
求最大的都包含1的matrix并返回面积
dp[i][j] means edge length of maximal square ending with matrix[i][j] as bottom-right corner
if matrix[i][j] == 1, state: dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
class Solution {
/*
dp[i][j] means edge length of maximal square ending with matrix[i][j] as bottom-right corner
if matrix[i][j] == 1 && matrix[i - 1][j] == 1 && matrix[i][j - 1] == 1, dp[i][j] = dp[i - 1][j - 1] + 1
state: dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
res:
res = max(res, dp[i][j] * dp[i][j])
*/
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;
int rows = matrix.length, cols = matrix[0].length;
int[][] dp = new int[rows][cols];
int res = 0;
//initialization
for (int i = 0; i < rows; i++) {
if (matrix[i][0] == '1') {
dp[i][0] = 1;
res = 1;
}
}
for (int j = 0; j < cols; j++) {
if (matrix[0][j] == '1') {
dp[0][j] = 1;
res = 1;
}
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < cols; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
res = Math.max(res, dp[i][j] * dp[i][j]);
}
}
}
return res;
}
}Count Square Submatrices with All Ones
maximal Square的升级版, 用的是同样的dp[i][j]的定义
dp[i][j] means edge length of maximal square ending with matrix[i][j] as bottom-right corner
这里有个小trick, dp[i][j] also means number of squares with matrix[i][j] as bottom-right corner
所以最后cnt = sum(dp[i][j])
Triangle
二维matrix DP的入门题
正常思维应该是首先想到DFS解法,traverse 或者D&C
然后分析DFS的时间复杂度,发现是指数级,并且画一下过程图,发现可以用memo优化成多项式级别
非常经典的题目来比较DFS, DFS with memo, DP的不同思路
DFS with memo是top-dwon, O(n^2) space
可以用bottom-up DP来优化成O(n) space
Minimum Path Sum
最简单的二维坐标DP
可以用滚动数组优化空间成O(min(n, m))
Last updated
Was this helpful?