LeetCode -- Maximal Square
Question:
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.
For example, given the following matrix:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
Return 4.
Analysis:
给出一个2D的二进制数组,找出正方形中完全由1组成的最大面积。
思路:
每次以当前元素(i, j)作为一个正方形的右下角或左上角。例如如果作为右下角,则对于当前元素为1的位置:dp[i][j] = min(dp[i-1][j-1] dp[i-1][j], dp[i][j-1]) + 1;(边长由四周中最小的边长加上当前元素的贡献)。刚开始是总是觉得这样实现只会求出边长为2的正方形,当边长为3或更多时就没法得到了。然而并不是。自己画个图把整个过程都走一下就明白了。
所以动态规划最重要的还是求得初始条件和状态转移方程。
对于本题:初始条件为第一行第一列都是原来的元素(边长只能为0或1);
状态转移方程为:dp[i][j] = min(dp[i-1][j-1] dp[i-1][j], dp[i][j-1]) + 1;
因此,代码如下:
public class Solution { public int getmin(int a, int b, int c) { int t = Math.min(a, b); int r = Math.min(t, c); return r; } public int maximalSquare(char[][] matrix) { if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0; int row = matrix.length, col = matrix[0].length; int[][] dp = new int[row][col]; int max = 0; for(int j=0; j<col; j++) { if(matrix[0][j] == '1') { dp[0][j] = 1; max = 1; } } for(int i=0; i<row; i++) { if(matrix[i][0] == '1') { dp[i][0] = 1; max = 1; } } for(int i=1; i<row; i++) { for(int j=1; j<col; j++) { if(matrix[i][j] == '1') dp[i][j] = getmin(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1; else dp[i][j] = 0; max = Math.max(max, dp[i][j]); } } return max * max; } }
小总结:其实做了这么多道动态规划的题目了,总的体型就一开始总结的那三种题型http://www.cnblogs.com/little-YTMM/p/5372680.html:LIS,背包问题,棋盘问题。将这三种体型灵活变通,学会应用,即可解决大部分的DP问题。