221. Maximal Square
问题:
给定有0和1构成的二维数组,
求数组中,连续 1 构成正方形的面积最大是多少。
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.length n == matrix[i].length 1 <= m, n <= 300 matrix[i][j] is '0' or '1'.
example 1:
example 2:
解法:DP
1.状态:dp[i][j]
- i,j:matrix[0~i][0~j]:包含最后一个cell在内,构成的最大满足题意的正方形 边长。
2.选择:
- matrix[i][j]==0:dp[i][j]=0
- matrix[i][j]==1:dp[i][j]= min {↖️左上格子为止最大正方形边长, ↑上方格子为止最大正方形边长,←右方格子为止最大正方形边长} + 1(扩展一格)
- = min { dp[i-1][j-1], dp[i-1][j], dp[i][j-1] } + 1
3.base:
- matrix[0][j]=0
- matrix[i][0]=0
4.♻️ 优化:dp由2维降维->1维
j不变,去掉 i。
- tmp保存本次即将被覆盖的dp[j]
- pre保存dp[j-1](原来👈 左边格子)最后将tmp赋给它。
- dp[j]代表原来⬆️ 上边格子。
- dp[j-1]代表原来↖️左上格子。
代码参考:
1 class Solution { 2 public: 3 //dp[i][j]: matrix[0~i][0~j] (last cell is 1) : max square's side length. 4 //opt: 5 //case_1: matrix[i][j]==0 -> dp[i+1][j+1]=0 6 //case_2: matrix[i][j]==1 -> dp[i+1][j+1]= min{dp[i-1][j], dp[i][j-1], dp[i-1][j-1]} + 1 7 //base: 8 //dp[0][0]=0 9 //dp[0][j]=0 10 //dp[i][0]=0 11 int maximalSquare(vector<vector<char>>& matrix) { 12 int n=matrix.size(), m=matrix[0].size(); 13 vector<int>dp(m+1, 0); 14 int maxlen = 0; 15 int pre=0; 16 for(int i=1; i<=n; i++) { 17 for(int j=1; j<=m; j++) { 18 int tmp = dp[j]; 19 if(matrix[i-1][j-1]=='0') dp[j]=0; 20 else { 21 dp[j] = min(min(pre, dp[j]), dp[j-1]) +1; 22 } 23 maxlen = max(maxlen, dp[j]); 24 pre = tmp; 25 } 26 } 27 return maxlen*maxlen; 28 } 29 };