Before attempting this problem, you should be comfortable with:
For each position in the output matrix, we need to find the maximum value in the corresponding 3x3 region of the input grid. The output matrix is (n-2) x (n-2) since we cannot center a 3x3 window on the edges. We simply iterate over all valid starting positions and scan the 3x3 window to find the maximum.
(n-2) x (n-2).(i, j) in the output matrix:(i, j) in the input grid.(i, j) in the output.class Solution:
def largestLocal(self, grid: List[List[int]]) -> List[List[int]]:
N = len(grid)
res = [[0] * (N - 2) for _ in range(N - 2)]
for i in range(N - 2):
for j in range(N - 2):
for r in range(i, i + 3):
for c in range(j, j + 3):
res[i][j] = max(res[i][j], grid[r][c])
return resWhile the simple iteration works well for a fixed 3x3 window, a Sparse Table allows us to answer any rectangular range maximum query in O(1) time after O(n^2 log^2 n) preprocessing. This is overkill for this specific problem but demonstrates a generalized technique useful when the window size varies or when we need to answer many range queries efficiently.
sparseTable[r][c][i][j] stores the maximum in the submatrix starting at (r, c) with dimensions (2^i) x (2^j).(x1, y1, x2, y2):(n-k+1) x (n-k+1) output position with window size k=3.class SparseTable:
def __init__(self, grid: List[List[int]]):
self.n = len(grid)
self.LOG = [0] * (self.n + 1)
for i in range(2, self.n + 1):
self.LOG[i] = self.LOG[i // 2] + 1
self.sparse_table = [[[[0] * (self.LOG[self.n] + 1) for _ in range(self.LOG[self.n] + 1)] for _ in range(self.n)] for _ in range(self.n)]
for r in range(self.n):
for c in range(self.n):
self.sparse_table[r][c][0][0] = grid[r][c]
for i in range(self.LOG[self.n] + 1):
for j in range(self.LOG[self.n] + 1):
for r in range(self.n - (1 << i) + 1):
for c in range(self.n - (1 << j) + 1):
if i == 0 and j == 0:
self.sparse_table[r][c][i][j] = grid[r][c]
elif i == 0:
self.sparse_table[r][c][i][j] = max(
self.sparse_table[r][c][i][j - 1],
self.sparse_table[r][c + (1 << (j - 1))][i][j - 1],
)
elif j == 0:
self.sparse_table[r][c][i][j] = max(
self.sparse_table[r][c][i - 1][j],
self.sparse_table[r + (1 << (i - 1))][c][i - 1][j],
)
else:
self.sparse_table[r][c][i][j] = max(
self.sparse_table[r][c][i - 1][j - 1],
self.sparse_table[r + (1 << (i - 1))][c][i - 1][j - 1],
self.sparse_table[r][c + (1 << (j - 1))][i - 1][j - 1],
self.sparse_table[r + (1 << (i - 1))][c + (1 << (j - 1))][i - 1][j - 1],
)
def query(self, x1: int, y1: int, x2: int, y2: int) -> int:
lx, ly = self.LOG[x2 - x1 + 1], self.LOG[y2 - y1 + 1]
return max(
self.sparse_table[x1][y1][lx][ly],
self.sparse_table[x2 - (1 << lx) + 1][y1][lx][ly],
self.sparse_table[x1][y2 - (1 << ly) + 1][lx][ly],
self.sparse_table[x2 - (1 << lx) + 1][y2 - (1 << ly) + 1][lx][ly],
)
class Solution:
def largestLocal(self, grid: List[List[int]]) -> List[List[int]]:
N, k = len(grid), 3
sparse_table = SparseTable(grid)
res = [[0] * (N - k + 1) for _ in range(N - k + 1)]
for i in range(N - k + 1):
for j in range(N - k + 1):
res[i][j] = sparse_table.query(i, j, i + k - 1, j + k - 1)
return resWhere is the size of the given square grid and is the fixed size of the submatrix window.
For an n x n input grid with a 3 x 3 window, the output matrix should be (n-2) x (n-2), not n x n or (n-1) x (n-1). This is because the 3x3 window cannot be centered on edge cells. Miscalculating the output dimensions leads to array index out of bounds errors or incorrect results.
When iterating over the 3x3 window starting at position (i, j), the window spans rows i to i+2 and columns j to j+2 (inclusive). A common mistake is using i+3 or j+3 as the upper bound in exclusive loop conditions but then accessing indices incorrectly, or confusing whether loop bounds should be inclusive or exclusive.