数据结构与算法:解码 LeetCode 221,解锁最大正方形
2024-02-18 09:22:07
在计算机科学的世界里,算法如同一道道耐人寻味的谜题,等待着人们去探索和破解。LeetCode 221 题正是这样一道妙趣横生的难题,它考验着程序员对动态规划的掌握程度,以及对问题本质的深刻理解。本文将带您踏上 LeetCode 221 的解题之旅,从动态规划的视角出发,层层剥开题目的奥秘,并用 JavaScript 语言为您呈现清晰易懂的代码实现。
题目背景
LeetCode 221 题的背景非常简单,它给定一个由 '0'
和 '1'
组成的二维矩阵,要求我们找到只包含 '1'
的最大正方形,并返回其面积。例如,对于以下矩阵:
[
["1", "0", "1", "0", "0"],
["1", "0", "1", "1", "1"],
["1", "1", "1", "1", "1"],
["1", "0", "0", "1", "0"]
]
最大正方形的边长为 3,因此面积为 9。
解题思路
解决 LeetCode 221 题的关键在于理解动态规划的思想。动态规划是一种解决问题的策略,它将大问题分解成一系列小问题,并逐一求解。在 LeetCode 221 题中,我们可以将矩阵的每个元素视为一个小问题,并利用动态规划的思想逐步求解。
具体来说,我们可以定义一个二维数组 dp
,其中 dp[i][j]
表示以 (i, j)
为右下角的子矩阵中,最大正方形的边长。我们从矩阵的左上角开始,逐行逐列地计算 dp
数组。当我们计算到 (i, j)
时,我们可以通过以下公式来计算 dp[i][j]
:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
其中:
dp[i-1][j]
表示以(i-1, j)
为右下角的子矩阵中,最大正方形的边长。dp[i][j-1]
表示以(i, j-1)
为右下角的子矩阵中,最大正方形的边长。dp[i-1][j-1]
表示以(i-1, j-1)
为右下角的子矩阵中,最大正方形的边长。
如果 matrix[i][j]
为 '0'
,则 dp[i][j]
为 0,因为以 (i, j)
为右下角的子矩阵中,不可能存在正方形。
代码实现
掌握了动态规划的解题思路后,我们就可以用 JavaScript 语言来实现算法。代码如下:
/**
* 给定一个由 '0' 和 '1' 组成的二维矩阵,找到只包含 '1' 的最大正方形,并返回其面积。
*
* @param {character[][]} matrix 二维矩阵
* @return {number} 最大正方形的面积
*/
const maximalSquare = function(matrix) {
if (!matrix || matrix.length === 0 || matrix[0].length === 0) {
return 0;
}
const m = matrix.length;
const n = matrix[0].length;
const dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
let maxSide = 0;
for (let i = 0; i < m; i++) {
dp[i][0] = matrix[i][0] === '1' ? 1 : 0;
maxSide = Math.max(maxSide, dp[i][0]);
}
for (let j = 0; j < n; j++) {
dp[0][j] = matrix[0][j] === '1' ? 1 : 0;
maxSide = Math.max(maxSide, dp[0][j]);
}
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
if (matrix[i][j] === '1') {
dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1;
maxSide = Math.max(maxSide, dp[i][j]);
}
}
}
return maxSide * maxSide;
};
结语
LeetCode 221 题是一道经典的算法题,它考验着程序员对动态规划的理解和应用能力。通过本文的讲解,您应该已经对 LeetCode 221 题的解题思路和代码实现有了清晰的认识。如果您想要进一步提高自己的算法能力,我建议您多多练习 LeetCode 上的题目,并不断总结和归纳解题经验。我相信,通过坚持不懈的努力,您一定能够成为一名优秀的算法工程师!