221. 最大正方形
- 暴力复杂度:\(O(n^4)\)
- 前缀和优化:\(O(n^3)\)
- 前缀和+二分优化:\(O(n^2\log n))\)
- 动态规划:\(O(n^2)\)
我们用 \(\textit{dp}(i, j)\) 表示以 \((i,j)\) 为右下角,且只包含 \(1\) 的正方形的边长最大值。如果我们能计算出所有 \(\textit{dp}(i, j)\) 的值,那么其中的最大值即为矩阵中只包含 \(1\) 的正方形的边长最大值,其平方即为最大正方形的面积。
那么如何计算 \(\textit{dp}\) 中的每个元素值呢?对于每个位置 \((i,j)\),检查在矩阵中该位置的值:
如果该位置的值是 \(0\),则 \(\textit{dp}(i, j) = 0\),因为当前位置不可能在由 \(1\) 组成的正方形中;
如果该位置的值是 \(1\),则 \(\textit{dp}(i, j)\) 的值由其上方、左方和左上方的三个相邻位置的 \(\textit{dp}\) 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 \(1\),状态转移方程如下:
\[dp(i, j)=min(dp(i−1, j), dp(i−1, j−1), dp(i, j−1))+1
\]
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int n = matrix.size(), m = matrix[0].size();
vector<vector<int>> f(n + 1, vector<int>(m + 1));
int res = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(matrix[i - 1][j - 1] == '1')
{
f[i][j] = min(f[i - 1][j], min(f[i][j - 1], f[i - 1][j - 1])) + 1;
res = max(res, f[i][j]);
}
return res * res;
}
};
```</int></vector<int></vector<char>