{x}
blog image

Magic Squares In Grid

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.length
  • col == grid[i].length
  • 1 <= row, col <= 10
  • 0 <= grid[i][j] <= 15

Solution Explanation and Code

This problem asks to find the number of 3x3 magic squares within a larger grid. A magic square is a 3x3 grid where the sum of each row, column, and both diagonals is the same.

The most straightforward approach is brute force enumeration. We iterate through all possible 3x3 subgrids within the input grid and check if each subgrid is a magic square.

Algorithm:

  1. Iterate through Subgrids: The outer loops iterate through all possible starting positions (top-left corner) of a 3x3 subgrid within the larger grid.

  2. Check for Magic Square: The check function performs the following checks:

    • Valid Numbers: Verifies that all numbers in the subgrid are within the range 1-9 and are distinct (using a set or array).
    • Row Sums: Calculates the sum of each row.
    • Column Sums: Calculates the sum of each column.
    • Diagonal Sums: Calculates the sum of both diagonals.
    • Consistent Sums: Checks if all row, column, and diagonal sums are equal. If all checks pass, it's a magic square.
  3. Count Magic Squares: The ans variable accumulates the count of magic squares found.

Time and Space Complexity:

  • Time Complexity: O(m*n), where 'm' and 'n' are the dimensions of the input grid. This is because we check each possible 3x3 subgrid, and the check function takes constant time.

  • Space Complexity: O(1). We use a small, constant amount of extra space to store variables for sums and the set of numbers.

Code Implementation (Python):

class Solution:
    def numMagicSquaresInside(self, grid: List[List[int]]) -> int:
        def check(i: int, j: int) -> int:
            if i + 3 > m or j + 3 > n:
                return 0
            s = set()
            row = [0] * 3
            col = [0] * 3
            a = b = 0
            for x in range(i, i + 3):
                for y in range(j, j + 3):
                    v = grid[x][y]
                    if v < 1 or v > 9:
                        return 0
                    s.add(v)
                    row[x - i] += v
                    col[y - j] += v
                    if x - i == y - j:
                        a += v
                    if x - i == 2 - (y - j):
                        b += v
            if len(s) != 9 or a != b:
                return 0
            if any(x != a for x in row) or any(x != a for x in col):
                return 0
            return 1
 
        m, n = len(grid), len(grid[0])
        return sum(check(i, j) for i in range(m) for j in range(n))
 

The code in other languages (Java, C++, Go, TypeScript, JavaScript) follows a very similar structure, differing only in syntax and data structure specifics. The core algorithm remains the same.

Optimized Solution (Concept):

While the brute-force approach is clear, an optimized solution could potentially use pre-computed information or clever pattern recognition to reduce the number of checks. However, given the relatively small size of the subgrids (3x3), the gains from optimization might be minimal for most inputs. The brute-force approach is likely sufficient for this problem's constraints.