Problem Statement in English
You’re given a 2D grid of characters. You have to count the number of submatrices that have an equal frequency of ‘X’ and ‘Y’. The submatrix must include the top left cell of the grid, and must have atleast one ‘X’.
Return the count of such submatrices.
Approach
To solve this problem, we can use a 2D prefix sum matrix. The prefix sum matrix allows us to quickly calculate the sum of any submatrix in constant time after an initial preprocessing step.
To do this, read up my post 304. Range Sum Query 2D - Immutable where I have explained how to build a 2D prefix sum matrix and query it.
And we’re done!
Solution in Python
class Solution:
def numberOfSubmatrices(self, grid: List[List[str]]) -> int:
M = len(grid)
N = len(grid[0])
matrix = [[[0, 0] for _ in range(N)] for _ in range(M)]
def repr(i, j):
c = grid[i][j]
if c == "X":
return [1, 0]
elif c == "Y":
return [0, 1]
return [0, 0]
def add(*vectors):
result = [0, 0]
for v in vectors:
result[0] += v[0]
result[1] += v[1]
return result
def subtract(x, y):
return [x[0] - y[0], x[1] - y[1]]
matrix[0][0] = repr(0, 0)
# build the first row
for j in range(1, N):
matrix[0][j] = add(matrix[0][j - 1], repr(0, j))
# build the first col
for i in range(1, M):
matrix[i][0] = add(matrix[i - 1][0], repr(i, 0))
# build 2D prefix sum
for i in range(1, M):
for j in range(1, N):
# grid this cell + matrix cell above + matrix cell left - matrix cell diag left
matrix[i][j] = subtract(
add(
repr(i, j),
matrix[i - 1][j],
matrix[i][j - 1],
),
matrix[i - 1][j - 1],
)
res = 0
# query the 2D prefix sum
for i in range(M):
for j in range(N):
if matrix[i][j][0] and matrix[i][j][0] == matrix[i][j][1]:
res += 1
return res
Complexity
Time: $O(M \times N)$
Where $M$ and $N$ are the dimensions of the grid. We build a 2D prefix sum in $O(M \times N)$ time and then query it in $O(M \times N)$ time.Space: $O(M \times N)$
We build a 2D prefix sum which takes $O(M \times N)$ space.
And we are done.