|
| 1 | +# [Problem 840: Magic Squares In Grid](https://leetcode.com/problems/magic-squares-in-grid/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +I need to count 3x3 subgrids that are magic squares: they must contain distinct numbers from 1 to 9 and each row, column and both diagonals sum to the same value. For a 3x3 magic square containing numbers 1..9 the magic sum is 15 (since sum 1..9 = 45, divided by 3 rows = 15). Also I recall a useful property: in any 3x3 1..9 magic square the center must be 5. That gives a quick filter. So for each possible 3x3 window, check that all 9 numbers are exactly the set {1..9} (or at least distinct and in 1..9) and that rows/cols/diagonals each sum to 15 (or check center==5 then sums). The grid is small (<=10x10) so brute force over all windows with O(1) checks per window is fine. |
| 5 | + |
| 6 | +## Refining the problem, round 2 thoughts |
| 7 | +Refine checks to be fast and simple: |
| 8 | +- Iterate over top-left corners i in [0..rows-3], j in [0..cols-3]. |
| 9 | +- For each window, quickly check center == 5 (prune many windows). |
| 10 | +- Validate all 9 numbers are in 1..9 and all distinct (use set equality with set(range(1,10)) or check set size 9 and range). |
| 11 | +- Check sums: each of 3 rows and 3 columns and both diagonals sum to 15. If all true, increment count. |
| 12 | + |
| 13 | +Edge cases: |
| 14 | +- grid smaller than 3x3 → return 0. |
| 15 | +- grid may contain zeros or values up to 15; those will fail the 1..9 check. |
| 16 | + |
| 17 | +Time complexity: O(rows * cols) windows, each window constant work (9 element checks and fixed number of sums) → O(R*C). Space is O(1) extra (ignoring negligible temporary list/set of size 9). |
| 18 | + |
| 19 | +## Attempted solution(s) |
| 20 | +```python |
| 21 | +from typing import List |
| 22 | + |
| 23 | +class Solution: |
| 24 | + def numMagicSquaresInside(self, grid: List[List[int]]) -> int: |
| 25 | + rows = len(grid) |
| 26 | + cols = len(grid[0]) if rows else 0 |
| 27 | + if rows < 3 or cols < 3: |
| 28 | + return 0 |
| 29 | + |
| 30 | + target_set = set(range(1, 10)) |
| 31 | + count = 0 |
| 32 | + |
| 33 | + for i in range(rows - 2): |
| 34 | + for j in range(cols - 2): |
| 35 | + # Quick center check: center must be 5 in any 3x3 magic square with numbers 1..9 |
| 36 | + if grid[i+1][j+1] != 5: |
| 37 | + continue |
| 38 | + |
| 39 | + # Collect the 3x3 values |
| 40 | + vals = [ |
| 41 | + grid[i + r][j + c] |
| 42 | + for r in range(3) |
| 43 | + for c in range(3) |
| 44 | + ] |
| 45 | + |
| 46 | + # Must contain all numbers 1..9 exactly once |
| 47 | + if set(vals) != target_set: |
| 48 | + continue |
| 49 | + |
| 50 | + # Check rows |
| 51 | + if (grid[i][j] + grid[i][j+1] + grid[i][j+2] != 15 or |
| 52 | + grid[i+1][j] + grid[i+1][j+1] + grid[i+1][j+2] != 15 or |
| 53 | + grid[i+2][j] + grid[i+2][j+1] + grid[i+2][j+2] != 15): |
| 54 | + continue |
| 55 | + |
| 56 | + # Check columns |
| 57 | + if (grid[i][j] + grid[i+1][j] + grid[i+2][j] != 15 or |
| 58 | + grid[i][j+1] + grid[i+1][j+1] + grid[i+2][j+1] != 15 or |
| 59 | + grid[i][j+2] + grid[i+1][j+2] + grid[i+2][j+2] != 15): |
| 60 | + continue |
| 61 | + |
| 62 | + # Check diagonals |
| 63 | + if (grid[i][j] + grid[i+1][j+1] + grid[i+2][j+2] != 15 or |
| 64 | + grid[i][j+2] + grid[i+1][j+1] + grid[i+2][j] != 15): |
| 65 | + continue |
| 66 | + |
| 67 | + # Passed all checks |
| 68 | + count += 1 |
| 69 | + |
| 70 | + return count |
| 71 | +``` |
| 72 | +- Notes: |
| 73 | + - Approach: brute-force all 3x3 windows with constant-time validation. Center==5 and set=={1..9} prune most candidates and ensure uniqueness and correct range. |
| 74 | + - Time complexity: O(R * C) windows, constant time per window => O(R*C). Given constraints (max 10x10), this is efficient. |
| 75 | + - Space complexity: O(1) extra (temporary list/set of size 9). |
0 commit comments