Maximal Square: using DP as a helper for an N^3 solution
Problem is to find the max square in a matrix, take a look: Maximal Square - LeetCode
Given an m x n binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.
Example 1:

Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] Output: 4
Example 2:

Input: matrix = [["0","1"],["1","0"]] Output: 1
Example 3:
Input: matrix = [["0"]] Output: 0
Constraints:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 300matrix[i][j]is'0'or'1'.
The idea is to use DP as a helper function. Imagine having every cell with two counters: the number of consecutive vertical 1s, and the number of consecutive horizontal 1s. This can be accomplished with DP in O(N^2)-time. Next, we go thru all cells and for each one that has a 1, we walk down the diagonal using the DP values to calculate the maximum square starting at that cell, and we keep track of the overall max. That takes O(N^3)-time. Given N=300, we're talking about 27M interactions which isn't that bad. Code is down below, cheers, ACC.
public class DPSquare
{
public int verticals = 0;
public int horizontals = 0;
public DPSquare(int verticals, int horizontals)
{
this.verticals = verticals;
this.horizontals = horizontals;
}
}
public int MaximalSquare(char[][] matrix)
{
DPSquare[][] dp = new DPSquare[matrix.Length][];
for (int i = 0; i < dp.Length; i++) dp[i] = new DPSquare[matrix[0].Length];
//DP O(n^2)
for (int r = 0; r < matrix.Length; r++)
{
for (int c = 0; c < matrix[r].Length; c++)
{
if (matrix[r][c] == '0')
{
dp[r][c] = new DPSquare(0, 0);
}
else
{
dp[r][c] = new DPSquare(1, 1);
if (r - 1 >= 0) dp[r][c].verticals += dp[r - 1][c].verticals;
if (c - 1 >= 0) dp[r][c].horizontals += dp[r][c - 1].horizontals;
}
}
}
//Calculate max O(n^3)
int max = 0;
for (int r = 0; r < matrix.Length; r++)
{
for (int c = 0; c < matrix[r].Length; c++)
{
if (matrix[r][c] == '1')
{
int tempRow = r;
int tempCol = c;
while (tempRow < matrix.Length &&
tempCol < matrix[r].Length &&
matrix[tempRow][tempCol] == '1' &&
dp[tempRow][tempCol].verticals >= tempRow - r + 1 &&
dp[tempRow][tempCol].horizontals >= tempCol - c + 1)
{
int area = (tempRow - r + 1) * (tempCol - c + 1);
max = Math.Max(max, area);
tempRow++;
tempCol++;
}
}
}
}
return max;
}
Comments
Post a Comment