leetcode 840. 矩阵中的幻方

编程入门 行业动态 更新时间:2024-10-11 05:29:57

leetcode 840. <a href=https://www.elefans.com/category/jswz/34/1769510.html style=矩阵中的幻方"/>

leetcode 840. 矩阵中的幻方

【题目】840. 矩阵中的幻方

3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。
给定一个由整数组成的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

示例:

输入: [[4,3,8,4],[9,5,1,9],[2,7,6,2]]
输出: 1
解释: 
下面的子矩阵是一个 3 x 3 的幻方:
438
951
276而这一个不是:
384
519
762总的来说,在本示例所给定的矩阵中只有一个 3 x 3 的幻方子矩阵。

提示:
1 <= grid.length <= 10
1 <= grid[0].length <= 10
0 <= grid[i][j] <= 15=

【解题思路1】按定义

可以在代码中添加 if grid[r+1][c+1] != 5: continue,帮助我们略过一些循环:

  • 网格的总和是 45,因为网格必须是 1 到 9 不同的数字。
  • 每一列和行加起来必须是 15,乘以 3 则是网格的总和。
  • 对角线的和也必须是 15,题目中说了对角线与列,行的和相同。
  • 将四条穿过中心的线的 12 个值相加(即一行一列两条对角线),这四条线加起来等于 60;而整个网
  • 格加起来为 45。则中心等于 (60-45)/3 = 5
class Solution {public int numMagicSquaresInside(int[][] grid) {int R = grid.length, C = grid[0].length;int ans = 0;for (int r = 0; r < R-2; ++r)for (int c = 0; c < C-2; ++c) {if (grid[r+1][c+1] != 5) continue;if (magic(grid[r][c], grid[r][c+1], grid[r][c+2],grid[r+1][c], grid[r+1][c+1], grid[r+1][c+2],grid[r+2][c], grid[r+2][c+1], grid[r+2][c+2]))ans++;}return ans;}public boolean magic(int... vals) {int[] count = new int[16];for (int v: vals) count[v]++;for (int v = 1; v <= 9; ++v)if (count[v] != 1)return false;return (vals[0] + vals[1] + vals[2] == 15 &&vals[3] + vals[4] + vals[5] == 15 &&vals[6] + vals[7] + vals[8] == 15 &&vals[0] + vals[3] + vals[6] == 15 &&vals[1] + vals[4] + vals[7] == 15 &&vals[2] + vals[5] + vals[8] == 15 &&vals[0] + vals[4] + vals[8] == 15 &&vals[2] + vals[4] + vals[6] == 15);}
}

【解题思路2】抽屉算法

另一种分析
满足幻方的条件必定是中间的数字为5,周围的数字为满足 1->6->7->2->9->4->3->8->1
的这种圆环结构,5的上下左右必定是 1、9、3、7(这四个数字都只能组成两组 15)
并且5的周围的数字其实都可以跳过,这里没作实现
1.利用数组的索引语义记录索引对应的下一个数字
2.若5的下一个值满足条件,且该值的下一行对应列满足条件,顺时针
若5的下一个值满足条件,且该值的上一行对应列满足条件,逆时针
3.总共判断6次即可(前两次已经判断过了)

class Solution {public int numMagicSquaresInside(int[][] grid) {//if(grid == null || grid.length < 3 || grid[1].length < 3)return 0;//由于是1~9的不同数字,那么必定是5在中间,并且其他数字满足顺时针或逆时针int[] check = {0,6,9,8,3,0,7,2,1,4};int result = 0;for(int i=1;i<grid.length-1;i++){for(int j=1;j<grid[0].length-1;j++){if(grid[i][j] == 5){int next = grid[i][j+1];switch(next){case 1:case 3:case 7:case 9:if(check[next] == grid[i+1][j+1]){if(each(grid,check,i+1,j+1,1))result++;}else if(check[next] == grid[i-1][j+1]){if(each(grid,check,i-1,j+1,-1))result++;}}//5的后一位必定不用算    j++;}}}return result;}public boolean each(int[][] grid,int[] check,int x,int y,int ward){int cur = grid[x][y];int next = check[cur];for(int i=y-2;y!=i;){if(grid[x][--y] != next)return false;cur = next;next = check[cur];}for(int i=x-2*ward;x!=i;){if(grid[x-=ward][y] != next)return false;cur = next;next = check[cur];}for(int i=y+2;y!=i;){if(grid[x][++y] != next)return false;cur = next;next = check[cur];}return true;       }
}

更多推荐

leetcode 840. 矩阵中的幻方

本文发布于:2024-02-13 17:46:57,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759576.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:矩阵   幻方   leetcode

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!