|
| 1 | +3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 |
| 2 | +给定一个由整数组成的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。 |
| 3 | +示例: |
| 4 | + |
| 5 | +```python |
| 6 | +输入: [[4,3,8,4], |
| 7 | + [9,5,1,9], |
| 8 | + [2,7,6,2]] |
| 9 | +输出: 1 |
| 10 | +解释: |
| 11 | +下面的子矩阵是一个 3 x 3 的幻方: |
| 12 | +438 |
| 13 | +951 |
| 14 | +276 |
| 15 | +而这一个不是: |
| 16 | +384 |
| 17 | +519 |
| 18 | +762 |
| 19 | +总的来说,在本示例所给定的矩阵中只有一个 3 x 3 的幻方子矩阵。 |
| 20 | +``` |
| 21 | + |
| 22 | +#### 分析: |
| 23 | +* 找出所有3*3的矩阵 |
| 24 | +* 判断是否有重复 |
| 25 | +* 判断是否在1-9之间 |
| 26 | +* 判断和是否相等 |
| 27 | + |
| 28 | +#### 方法一:最笨的方法 |
| 29 | +```python |
| 30 | +def numMagicSquaresInside(grid): |
| 31 | + rows = len(grid) |
| 32 | + columns = len(grid[0]) |
| 33 | + if rows < 3 or columns < 3: |
| 34 | + return 0 |
| 35 | + |
| 36 | + all_list_3_3 = [] |
| 37 | + for r in range(0, rows-2): |
| 38 | + for c in range(0, columns-2): |
| 39 | + # 判断有没有重复的 |
| 40 | + if len(set(grid[r][c:c + 3] + grid[r+1][c:c+3] + grid[r+2][c:c+3])) != 9: |
| 41 | + continue |
| 42 | + # 判断元素在1-9之间 |
| 43 | + is_can = True |
| 44 | + for i in range(0, 3): |
| 45 | + if not (1 <= grid[r][c:c + 3][i] <= 9 and |
| 46 | + 1 <= grid[r+1][c:c + 3][i] <= 9 and |
| 47 | + 1 <= grid[r+2][c:c + 3][i] <= 9): |
| 48 | + is_can = False |
| 49 | + break |
| 50 | + if is_can: |
| 51 | + list_3_3 = [] |
| 52 | + list_3_3.append(grid[r][c:c+3]) |
| 53 | + list_3_3.append(grid[r+1][c:c+3]) |
| 54 | + list_3_3.append(grid[r+2][c:c+3]) |
| 55 | + all_list_3_3.append(list_3_3) |
| 56 | + count = 0 |
| 57 | + for list_3_3 in all_list_3_3: |
| 58 | + if sum(list_3_3[0]) == sum(list_3_3[1]) == sum(list_3_3[2]): |
| 59 | + col_sum_1 = list_3_3[0][0] + list_3_3[1][0] + list_3_3[2][0] |
| 60 | + col_sum_2 = list_3_3[0][1] + list_3_3[1][1] + list_3_3[2][1] |
| 61 | + col_sum_3 = list_3_3[0][2] + list_3_3[1][2] + list_3_3[2][2] |
| 62 | + if col_sum_1 == col_sum_2 == col_sum_3: |
| 63 | + diag_sum_1 = list_3_3[0][0] + list_3_3[1][1] + list_3_3[2][2] |
| 64 | + diag_sum_2 = list_3_3[0][2] + list_3_3[1][1] + list_3_3[2][0] |
| 65 | + if diag_sum_1 == diag_sum_2: |
| 66 | + count += 1 |
| 67 | + |
| 68 | + return count |
| 69 | +``` |
| 70 | + |
| 71 | +#### 方法二:分析规律 |
| 72 | +```python |
| 73 | +# 网格的总和是 45,因为网格必须是 1 到 9 不同的数字。 |
| 74 | +# 每一列和行加起来必须是 15,乘以 3 则是网格的总和。 |
| 75 | +# 对角线的和也必须是 15,题目中说了对角线与列,行的和相同。 |
| 76 | +# 将四条穿过中心的线的 12 个值相加(即一行一列两条对角线), |
| 77 | +# 这四条线加起来等于 60;而整个网格加起来为 45。 |
| 78 | +# 则中心等于 (60-45)/3 = 5 |
| 79 | +def numMagicSquaresInside(grid): |
| 80 | + rows = len(grid) |
| 81 | + columns = len(grid[0]) |
| 82 | + if rows < 3 or columns < 3: |
| 83 | + return 0 |
| 84 | + |
| 85 | + def magic(a, b, c, d, e, f, g, h, i): |
| 86 | + if (sorted([a, b, c, d, e, f, g, h, i]) == list(range(1, 10)) |
| 87 | + and |
| 88 | + (a + b + c == d + e + f == g + h + i == a + d + g == b + e + h == c + f + i == a + e + i == c + e + g == 15)): |
| 89 | + return True |
| 90 | + |
| 91 | + count = 0 |
| 92 | + for r in range(0, rows-2): |
| 93 | + for c in range(0, columns-2): |
| 94 | + if grid[r+1][c+1] != 5: |
| 95 | + # 中心元素必须是5 |
| 96 | + continue |
| 97 | + if magic(grid[r][c], grid[r][c + 1], grid[r][c + 2], |
| 98 | + grid[r + 1][c], grid[r + 1][c + 1], grid[r + 1][c + 2], |
| 99 | + grid[r + 2][c], grid[r + 2][c + 1], grid[r + 2][c + 2]): |
| 100 | + count += 1 |
| 101 | + return count |
| 102 | +``` |
0 commit comments