1.問題の説明:
0と1で構成される2次元行列で、1のみを含む最大の正方形を見つけ、その面積を返します。
例:
入力してください:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
出力:4
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/maximal-square
2.思考分析:
①最初はブルートフォースを使ってクラックできます。最初は4層のループを使って書くと思っていましたが、ループが多すぎて少しわかりにくいので、公式の解決策を調べたところ、以下のアイデアがブルートフォースに使えることがわかりました。
1つ目は、2次元配列をトラバースすることです。1であることがわかった場合は、より大きな正方形を形成することができます。まず、現在の位置1に対応する次の線がすべての条件を満たし、現在の位置1であるかどうかにかかわらず、長さ2の正方形を試してください。右の列が条件を満たすかどうか。次の行と右の列を確認すると、長さ2の正方形が条件を満たすかどうかがわかります。最も外側のレイヤーはループを使用して正方形を拡張でき、現在の辺の長さが数正方形であることを示しています。ここで、 0が見つかったときに現在の長さが正方形を形成できないことを示すフラグを設定します。以下は、正方形の拡張が条件を満たすかどうかを確認するための概略図です。
②ブルートフォースクラッキングの手法に加えて、動的計画法を利用することもできます。現在位置が1のときに形成される最大の正方形は、上、左、左上隅の正方形の数で制約される必要があるため、必要です。現在の位置で形成された最大の正方形を示すために、最小値のみを取り出すことができます。カラーボタンのソリューションを参照できます:https : //leetcode-cn.com/problems/maximal-square/solution/li-jie-san- zhe-qu-zui-xiao-1-by-lzhlyle /、その中に写真があります。動的プログラミングを少し理解する方が良いです。アイデアを得るには、さらに多くの動的計画トピックを見て、特定の分析のためにグラフィックスを組み合わせる必要があると思います。クリックしてdp配列を取得
③暴力の公式解決策を書き直したので、総当たり攻撃の考え方に慣れる
3.コードは次のとおりです。
ブルートフォースコード:
import java.util.Scanner;
public class Solution {
public int maximalSquare(char[][] matrix) {
int r = matrix.length, c = r > 0 ? matrix[0].length : 0;
int max = 0;
for (int i = 0; i < r; ++i){
for (int j = 0; j < c; ++j){
if (matrix[i][j] == '1'){
int curLen = 1;
int f = 1;
while (i + curLen < r && j + curLen < c && f == 1){
for (int k = j; k <= j + curLen; ++k){
if (matrix[i + curLen][k] == '0'){
f = 0;
break;
}
}
/*检查列*/
for (int l = i; l <= i + curLen; ++l){
if (matrix[l][j + curLen] == '0'){
f = 0;
break;
}
}
if (f == 1){
curLen++;
}
}
max = Math.max(max, curLen);
}
}
}
return max * max;
}
}
公式の動的計画コード:
import java.util.Scanner;
public class Solution {
public int maximalSquare(char[][] matrix) {
int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;
int[][] dp = new int[rows + 1][cols + 1];
int maxsqlen = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
if (matrix[i-1][j-1] == '1'){
dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
maxsqlen = Math.max(maxsqlen, dp[i][j]);
}
}
}
return maxsqlen * maxsqlen;
}
}