Maximal Square
Medium · 2-D Dynamic Programming · Explanation and code example
Dynamic Programming (Space Optimized)
How it works
The bottom-up DP only needs the current row and the next row to compute values. We can reduce space by using a single 1D array. As we process each row from right to left, we keep track of the previous diagonal value in a variable prev. This allows us to update the array in place while still having access to all three neighbors needed for the recurrence.
Steps
- Create a 1D DP array of size
n+1initialized to0. - Iterate from
r = m-1down to0:- Set
prev = 0(represents the diagonal value from the previous iteration). - For each column
cfromn-1down to0:- Store
dp[c]intemp(this will be the next diagonal). - If
matrix[r][c]is'1', setdp[c] = 1 + min(dp[c], dp[c+1], prev)and updatemaxSquare. - Otherwise, set
dp[c] = 0. - Update
prev = temp.
- Store
- Set
- Return
maxSquare * maxSquare.
Complexity
- Time complexity:
O(m * n) - Space complexity:
O(n)
Where
mis the number of rows andnis the number columns.
Things to watch for
Returning the Side Length Instead of the Area
The DP table stores the side length of the largest square, but the problem asks for the area. Forgetting to square the maximum side length before returning gives an incorrect answer.
Comparing Characters Instead of Character Values
Matrix elements are characters ('0' and '1'), not integers. Comparing against integer 0 or 1 instead of character '0' or '1' causes the condition to always evaluate incorrectly, resulting in wrong DP values.
Incorrect DP Recurrence Direction
The recurrence dp[r][c] = 1 + min(dp[r+1][c], dp[r][c+1], dp[r+1][c+1]) assumes processing from bottom-right to top-left. Processing in the wrong direction (top-left to bottom-right without adjusting the formula) references uncomputed values and produces incorrect results.
Python code example
from typing import List
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
m, n = len(matrix), len(matrix[0])
dp = [0] * (n + 1)
max_square = 0
for r in range(m - 1, -1, -1):
prev = 0
for c in range(n - 1, -1, -1):
temp = dp[c]
if matrix[r][c] == "1":
dp[c] = 1 + min(dp[c], dp[c + 1], prev)
max_square = max(max_square, dp[c])
else:
dp[c] = 0
prev = temp
return max_square * max_square
C++ code example
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<int> dp(n + 1, 0);
int maxSquare = 0;
for (int r = m - 1; r >= 0; r--) {
int prev = 0;
for (int c = n - 1; c >= 0; c--) {
int temp = dp[c];
if (matrix[r][c] == '1') {
dp[c] = 1 + min({dp[c], dp[c + 1], prev});
maxSquare = max(maxSquare, dp[c]);
} else {
dp[c] = 0;
}
prev = temp;
}
}
return maxSquare * maxSquare;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.