題目地址:Maximal Square
題目簡介:
在一個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大正方形,並返回其面積。
示例:
Input:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Output: 4
輸出4的原因是第2行和第3行中組成了2x2的正方形。
題目分析:
1、簡單法
正方形的左上角也是正方形,正方形的最小邊長爲1。所以只要碰到'1',按照正方行對角線擴展,邊長每增加1,對應輪廓增加1。從左上到右下,只要保證每次擴展的邊界沒有'0',便可以增加輪廓。
C++:
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty() || matrix[0].empty())
return 0;
int ans = 0, row = matrix.size(), col = matrix[0].size();
for (int i = 0; i < row;i++)
for (int j = 0; j < col; j++)
if (matrix[i][j] == '1')
ans = max(ans, helper(i, j, matrix));
return ans;
}
int helper(int x, int y, vector<vector<char>>& matrix){
int circle = 1;
bool flag = true;
int row = matrix.size(), col = matrix[0].size();
while(flag)
{
circle++;
if (x + circle <= row && y + circle <= col)
{
for (int i = x; i < x + circle;i++)
{
if(matrix[i][y + circle - 1] == '0')
{
flag = false;
circle--;
return pow(circle, 2);
}
}
for (int j = y; j < y + circle;j++)
{
if(matrix[x + circle - 1][j] == '0')
{
flag = false;
circle--;
return pow(circle, 2);
}
}
}
else
{
flag = false;
circle--;
}
}
return pow(circle, 2);
}
};
Python:
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
if len(matrix) == 0 or len(matrix[0]) == 0:
return 0
ans = 0
row = len(matrix)
col = len(matrix[0])
def helper(x, y):
circle = 1
# flag = True
while True:
circle += 1
if x + circle <= row and y + circle <= col:
for i in range(x , x + circle):
if matrix[i][y + circle - 1] == '0':
# flag = False
circle -= 1
return pow(circle, 2)
for j in range(y, y + circle):
if matrix[x + circle - 1][j] == '0':
# flag = False
circle -= 1
return pow(circle, 2)
else:
# flag = False
circle -= 1
return pow(circle, 2)
for i in range(row):
for j in range(col):
if matrix[i][j] == '1':
ans = max(ans, helper(i, j))
return ans
2、遞歸
考慮這樣一個例子:
1 1 1
1 1 1
1 1 1
這個例子中,假設已經知道除了不加右下角的1之外的所有最大面積。那麼怎麼得到包含右下角1的最大面積呢?首先,根據上面可知,右下角鄰接的3個左、上、左上所能組成的均是一個2x2的正方形。那麼,當左邊的正方形被破壞呢?
1 1 1
1 1 1
0 1 1
其能組成的面積,要依賴左邊點的面積。此時左邊最大爲1,組成結果爲2x2。那麼此時再將上面兩個1破壞呢?
1 1 1
1 0 0
0 1 1
這個時候,左上和上的最大面積僅爲0,所以,這時也組成不了2x2的面積,只能爲1x1。總結一個規律就是:
C++:
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty())
return 0;
int row = matrix.size(), col = matrix[0].size(), ans = 0;
vector<vector<int>> dp(row, vector<int>(col, 0));
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (!i || !j || matrix[i][j] == '0')
{
dp[i][j] = matrix[i][j] - '0';
}
else
{
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
}
ans = max(dp[i][j], ans);
}
}
return pow(ans, 2);
}
};
Python:
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
if len(matrix) == 0 or len(matrix[0]) == 0:
return 0
ans = 0
row = len(matrix)
col = len(matrix[0])
dp = [[0 for j in range(col)] for i in range(row)]
for i in range(row):
for j in range(col):
if (not i or not j or matrix[i][j] == '0'):
dp[i][j] = ord(matrix[i][j]) - ord('0')
else:
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1
ans = max(dp[i][j], ans)
return pow(ans, 2)