持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情
最近一直在力扣刷题,也逐渐对各类题型有了自己的理解,所谓见招拆招,将自己的浅显经验分享一下,帮助更多在编程路上的朋友们。
最大正方形
在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。
示例 1:
输入: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出: 4
示例 2:
输入: matrix = [["0","1"],["1","0"]]
输出: 1
示例 3:
输入: matrix = [["0"]]
输出: 0
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 300matrix[i][j]为'0'或'1'
思路
题目要求找到最大的正方形面积,我们只需要找到最大的正方形边长即可,最后返回边长的平方。
遍历一次二维数组就需要O(mn)的时间复杂度,如果对每一个点进行遍历,再根据该点寻找最长的边长,则时间复杂度会更大,虽然测试用例中 m 和 n 的数据量很小,但暴力法能不用就尽量不要用。我们可以发现前一状态的边长长度是可以保存的,故采用动态规划的方法。
dp[i][j]代表以(i, j)为右下角正方形的最大边长。
对于(i, j)位置,如果matrix[i][j] == '1',则该位置的最大边长由左、左上、上方向的三个相邻位置的最大边长决定的。取三个位置中的最小边长 + 1 即为该位置的最大边长。状态转移方程为dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i][j - 1], dp[i - 1][j - 1])) + 1
题解
class Solution {
public int maximalSquare(char[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m + 1][n + 1];
int max = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(matrix[i][j] == '1') {
dp[i + 1][j + 1] = Math.min(dp[i + 1][j], Math.min(dp[i][j + 1], dp[i][j])) + 1;
max = Math.max(dp[i + 1][j + 1], max);
}
}
}
return max * max;
}
}