A 3 x 3 magic square is a 3 x 3 grid filled with distinct numbers from 1 to 9 such that each row, column, and both diagonals all have the same sum.
Given a row x col grid of integers, how many 3 x 3 magic square subgrids are there?
Note: while a magic square can only contain numbers from 1 to 9, grid may contain numbers up to 15.
Example 1:
Input: grid = [[4,3,8,4],[9,5,1,9],[2,7,6,2]] Output: 1 Explanation: The following subgrid is a 3 x 3 magic square:while this one is not:
In total, there is only one magic square inside the given grid.
Example 2:
Input: grid = [[8]] Output: 0
Constraints:
row == grid.lengthcol == grid[i].length1 <= row, col <= 100 <= grid[i][j] <= 15When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding magic squares in a grid involves examining every possible small square within the larger grid. For each small square, we check if it possesses the properties of a magic square. If it does, we count it; if not, we move on to the next possible small square.
Here's how the algorithm would work step-by-step:
def num_magic_squares_inside(grid):
row_length = len(grid)
column_length = len(grid[0])
magic_square_count = 0
for row in range(row_length - 2):
for column in range(column_length - 2):
# Iterate through all possible 3x3 subgrids
if is_magic_square(grid, row, column):
magic_square_count += 1
return magic_square_count
def is_magic_square(grid, row, column):
numbers = []
for i in range(row, row + 3):
for j in range(column, column + 3):
numbers.append(grid[i][j])
#Verify all digits from 1 to 9 are present
if set(numbers) != set(range(1, 10)):
return False
total = 15
if grid[row][column] + grid[row][column+1] + grid[row][column+2] != total:
return False
if grid[row+1][column] + grid[row+1][column+1] + grid[row+1][column+2] != total:
return False
if grid[row+2][column] + grid[row+2][column+1] + grid[row+2][column+2] != total:
return False
if grid[row][column] + grid[row+1][column] + grid[row+2][column] != total:
return False
if grid[row][column+1] + grid[row+1][column+1] + grid[row+2][column+1] != total:
return False
if grid[row][column+2] + grid[row+1][column+2] + grid[row+2][column+2] != total:
return False
# Check the diagonals
if grid[row][column] + grid[row+1][column+1] + grid[row+2][column+2] != total:
return False
if grid[row][column+2] + grid[row+1][column+1] + grid[row+2][column] != total:
return False
return TrueTo find magic squares in a grid, we avoid brute-force checking every possible square. We focus on a clever method to quickly identify potential magic squares based on their central number and row/column sums. This reduces the number of squares we need to fully validate, significantly improving efficiency.
Here's how the algorithm would work step-by-step:
def magic_squares_in_grid(grid):
row_length = len(grid)
column_length = len(grid[0])
magic_square_count = 0
for row in range(row_length - 2):
for column in range(column_length - 2):
# Check if the center element is 5
if grid[row+1][column+1] != 5:
continue
subgrid = []
for i in range(3):
for j in range(3):
subgrid.append(grid[row+i][column+j])
# Check if all numbers from 1 to 9 are present
if len(set(subgrid)) != 9 or min(subgrid) != 1 or max(subgrid) != 9:
continue
# Check if rows, columns, and diagonals sum to 15
if (grid[row][column] + grid[row][column+1] + grid[row][column+2] == 15 and\
grid[row+1][column] + grid[row+1][column+1] + grid[row+1][column+2] == 15 and\
grid[row+2][column] + grid[row+2][column+1] + grid[row+2][column+2] == 15 and\
grid[row][column] + grid[row+1][column] + grid[row+2][column] == 15 and\
grid[row][column+1] + grid[row+1][column+1] + grid[row+2][column+1] == 15 and\
grid[row][column+2] + grid[row+1][column+2] + grid[row+2][column+2] == 15 and\
grid[row][column] + grid[row+1][column+1] + grid[row+2][column+2] == 15 and\
grid[row][column+2] + grid[row+1][column+1] + grid[row+2][column] == 15):
magic_square_count += 1
return magic_square_count| Case | How to Handle |
|---|---|
| Null or empty grid | Return 0 immediately as no magic square can exist. |
| Grid dimensions less than 3x3 | Return 0 since a magic square requires at least 3 rows and 3 columns. |
| Grid containing values outside the range [1, 9] | The isMagicSquare function should validate each cell value is within [1, 9]; if not, the square is not magic. |
| Grid with extremely large dimensions (performance) | The solution should avoid unnecessary computations within the sliding window approach for efficiency. |
| No magic squares present in the grid | The algorithm should correctly return 0 if no 3x3 subgrid satisfies the magic square property. |
| Multiple overlapping magic squares | The sliding window approach implicitly handles overlapping magic squares, counting each valid one. |
| Integer overflow when calculating sums | Use appropriate data types (e.g., int) to prevent potential overflow when summing rows, columns, and diagonals. |
| Grid contains only one unique value within the range [1,9] | The isMagicSquare function should return false since a magic square requires distinct values to satisfy the sum conditions. |