위 사각형을 생각해보면 이해가 좀 더 편하다. 만약 dp[i][j] (=DP[Y][X])가 정사각형이라면, 위 세 영역중 제일 값이 작은 값(2)을 기준으로 새로 최대 정사각형을 그릴 수 있다.
이런 식으로 DP가 정의되며, 이 과정이 직관적으로 이해될것이다.
또, DP[Y][X] = n이라면 오른쪽 아래 좌표가 (X,Y)인 정사각형이 변의 길이 1부터 n까지 존재할 수 있다.
따라서 본 질문은 DP matrix를 구하고, 그 matrix의 총합을 구하는 문제로 바꿀 수 있다. 시간복잡도는 O(N^2)이다.
풀이 코드
class Solution:
def countSquares(self, matrix: List[List[int]]) -> int:
X, Y = len(matrix[0]), len(matrix)
dp = [[0]*X for _ in range(Y)]
result = 0
for y in range(Y) :
for x in range(X) :
if matrix[y][x] :
result += 1
dp[y][x] = 1
if y > 0 and x > 0 :
minlen = min(dp[y-1][x], dp[y][x-1], dp[y-1][x-1])
result += minlen
dp[y][x] = max(dp[y][x], minlen+1)
return result
풀이 코드 (좀 더 공간 효율적인 버전)
class Solution:
def countSquares(self, matrix: List[List[int]]) -> int:
X, Y = len(matrix[0]), len(matrix)
for y in range(1, Y) :
for x in range(1, X) :
if matrix[y][x] :
matrix[y][x] += min(matrix[y-1][x], matrix[y][x-1], matrix[y-1][x-1])
return sum(map(sum, matrix))