注意的几个点:
1.main()
动态内存分配矩阵,注意二维的格式:
char** matrix = (char**)malloc(sizeof(char*) * n); for (int i = 0; i < n; i++) { matrix[i] = (char*)malloc(sizeof(char) * m); }
(可以理解为先行再列)
释放的时候也是要注意格式:
for (int i = 0; i < n; i++) { free(matrix[i]); } free(matrix);
2.还有一个就是main里面我为什么用了char,而不是int,我是为了省点空间,当然你用int也是完全OK的,改的时候记得把自定义函数改回去
3.dp的内在逻辑:
(1)先是初定义
for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (matrix[i][j] == 1) { dp[i][j] = (i == 0 || j == 0) ? 1 : (min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1); max_side = (dp[i][j] > max_side) ? dp[i][j] : max_side; } else { dp[i][j] = 0; } } }
(2)然后遍历
定义dp[i][j]是正方形的右下角(当i == 0 || j == 0)即为第一行或第一列时,边长都为1(题目要求正方形),然后从[1][1]开始,正左,左上,正上的比,如果该点是1(则取三个方向最小的,再加1,比如0+1,1+1这样(有点绕,但能理解,读者可以画画图)),如果该点是0,则要归0重来
总结一下就是三个方向都不是0,且该点为1,取最小加1;如果是0,则要重新来,应该都懂了
4.max_side是用来维护当前最优的,这是dp一个很重要的点
#include <stdio.h>
#include <stdlib.h>
#define min(a, b) ((a) < (b) ? (a) : (b))
int maximalSquare(char** matrix, int n, int m) {
int** dp = (int**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
dp[i] = (int*)malloc(sizeof(int) * m);
}
int max_side = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = (i == 0 || j == 0) ? 1 : (min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1);
max_side = (dp[i][j] > max_side) ? dp[i][j] : max_side;
}
else {
dp[i][j] = 0;
}
}
}
for (int i = 0; i < n; i++) {
free(dp[i]);
}
free(dp);
return max_side ;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
char** matrix = (char**)malloc(sizeof(char*) * n);
for (int i = 0; i < n; i++) {
matrix[i] = (char*)malloc(sizeof(char) * m);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf(" %c", &matrix[i][j]);
}
}
printf("%d\n", maximalSquare(matrix, n, m));
for (int i = 0; i < n; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}