首先來想要怎樣去找任意一個正方形的面積。
如果選定某一位置,那正方形會在往右下延伸、或左上,簡單來說就是四周。
不過這樣相當不容易寫,而且也會效率不佳。
再觀察一下,正方形出現時會有怎樣的情形?
假設有個面積為 4 的正方形:
![]() |
基礎假設 |
可以發現組成邊長2的正方形,其相鄰加身自身會有2個連續出現1超過二次。
同理邊長為3的正方形。
![]() |
計算流程 |
於是各欄只要計數1的連續出現次數,接下來問題變成要如何從數列中找出最大的正方形面積。
接著要去從數列中求出最大的正方形面積。
我這裡使用暴力破解法,以自身為左右索引的起始點,往左右找有大於自身數值的個數。
如 2 ,只要往左右再找一個,因為自身本身可以當作一個計數。
過程中,數值小於當前的最大面積的邊長也可以跳過不往左右找。
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
if not matrix or not matrix[0]: return 0
rows,cols= len(matrix), len(matrix[0])
cur = [0]*cols
maxSideLength = 0
for y in range(rows):
# 逐行掃瞄
for x in range(cols):
if matrix[y][x] == "1":
cur[x] += 1
else:
cur[x] = 0
# 檢查連續最大值
for x in range(cols):
v = cur[x]
if v <= maxSideLength: continue
v -= 1
l, r = x, x
while v:
if l > 0 and cur[l-1] >= cur[x]:
l-=1
v-=1
continue
if r = cur[x]:
r+=1
v-=1
continue
break
if v==0:
maxSideLength = max(maxSideLength, cur[x])
return maxSideLength**2
C#
public class Solution {
public int MaximalSquare(char[][] matrix) {
if(matrix.Length == 0 || matrix[0].Length == 0){return 0;}
var cur = new int[matrix[0].Length];
Array.Fill(cur, 0);
int maxSideLength = 0;
for(int y = 0; y < matrix.Length; y++)
{
for(int x = 0; x < matrix[0].Length; x++)
{
if(matrix[y][x]=='1')
{
cur[x] += 1;
}
else
{
cur[x] = 0;
}
}
for(int x = 0; x < matrix[0].Length; x++)
{
if(cur[x] <= maxSideLength)
{
continue;
}
int num = cur[x]-1;
int l = x; int r = x;
while(num > 0)
{
if(l > 0 && cur[l-1] >= cur[x])
{
l -= 1;
num -= 1;
continue;
}
if(r = cur[x])
{
r += 1;
num -= 1;
continue;
}
break;
}
if(num==0)
{
maxSideLength = cur[x];
}
}
}
return maxSideLength*maxSideLength;
}
}