444 字
2 分钟
LeetCode 题解-221. Maximal Square
对Leetcode 221. Maximal Square 题目的求解。
Problem Description
Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.
Example
Input:1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0
Output: 4Analysis
看到网格类题目,首先想到动态规划。既然要用动态规划,我们必须要找到递归规律。我们很自然的想到,用dp[i][j]表示以(i,j)为右下角的最大的正方形。那么
- 如果matrix[i][j]为0,则dp[i][j]必为0
- 如果matrix[i][j]为1,则有两种情况
- dp[i-1][j-1] > max(dp[i-1][j], dp[i][j-1]) 这种情况下,我们最大能得到min(dp[i-1][j], dp[i][j-1])+1的正方形。
- dp[i-1][j-1] < max(dp[i-1][j], dp[i][j-1]) 这种情况下,我们最大能得到dp[i-1][j-1]+1的正方形。
所以dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
Solution 1
public static int maximalSquare(char[][] matrix) { //right down corner if (matrix.length < 1 || matrix[0].length < 1) return 0; int dp[][] = new int[matrix.length + 1][matrix[0].length + 1]; int max = 0; for (int i = 1; i < dp.length; ++i){ for (int j = 1; j < dp[i].length; ++j){ if (matrix[i-1][j-1] == '0') dp[i][j] = 0; else dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1; max = Math.max(dp[i][j], max); } } return max*max;}Solution 2
事实上,我们并不需要mxn的矩阵来储存所有的dp元素,2xn的矩阵即可,由此我们可以将空间复杂度降低至O(n),达到理论上最优。
public static int maximalSquare(char[][] matrix) { //right down corner if (matrix.length < 1 || matrix[0].length < 1) return 0; int dp[][] = new int[2][matrix[0].length + 1]; int max = 0; for (int i = 1; i < matrix.length + 1; ++i){ for (int j = 1; j < matrix[0].length + 1; ++j){ int cur = (i-1) % 2; int prev = i % 2; if (matrix[i-1][j-1] == '0') dp[cur][j] = 0; else dp[cur][j] = Math.min(Math.min(dp[prev][j], dp[cur][j-1]), dp[prev][j-1]) + 1; max = Math.max(dp[cur][j], max); } }
return max*max;}Solution 3
那么,时间复杂度还有没有优化的空间呢?好像没有了,但是我的代码只能击败5%的人,为什么呢?