判断数独是否正确

绪论

这个题目是我在校招面试某家大公司的在线笔试题(不是BAT),当时第一次用程序做数独,时间也来不及,就没有很好的做出来。(在这里吐槽一下,一个小时10道选择10道填空,2道编程题,确实时间有点紧了,不过编程题难度还没有美团的高),有点难受,所以写下了这篇文章。

当然,真正的题目有差别,我这里主要是通过整型数组来实现,展示一下原理。我也是个菜鸡,有什么不正确的请联系本人,谢谢。


目录

判断数独是否正确

数独定义

逻辑分析

矩阵遍历

行遍历

列遍历

总代码

测试


数独定义

数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。【摘自:百度百科】

注:该文中用 0 表示空格,未填写,因为方格中只能填入 [1,9]

逻辑分析

话不多说,先上图

如果你是第一次用程序的角度来做这道题,不用每一个方格都去判断方格所在行列以及矩阵无重复元素,这样其实做了大量的重复操作,我们需要的是一步到位,简单便捷。

行列无重复元素:遍历对角线,时间复杂度O(n),可以遍历到每一行每一列。

小矩阵无重复元素:将大矩阵划分为9个小矩阵,小矩阵中遍历一次判断有无重复元素。时间复杂度O(n*n)

行列遍历的原理:

这里通过对角线,遍历了整个每行每列。当然你可以拆分成单独遍历一次每行,一次每列。差别不大

矩阵遍历

这里我将四重循环写成了双重

/*** 检查小矩阵内的数字* @return 布尔值*/public static boolean checkSubMatrix(int[][] matrix){boolean flag = true;int y = 0;int x = 0;while(flag&&(y<3)){int startX = 3*x;int startY = 3*y;while(flag&&(startY<3*y+3)){Set<Integer> set = new HashSet<>();if (0<matrix[startY][startX]&&matrix[startY][startX]<10){flag = set.add(matrix[startY][startX]);}startX++;if (startX>=3*x+3){startY++;startX = 3*x;}}x++;if (x>=3){y++;x=0;}}return flag;}

这里我解释一下上面代码的变量:

第一个小矩阵:x:[0,3) y:[0,3)

第一个小矩阵:x:[3,6) y:[3,6)

.....

矩阵的横/纵坐标开始可表示为 3*0 3*1 3*2,当然这里因为数独,直接将3写死,因为数独是9*9的矩阵。

每个小矩阵的边长都是三,StartX和StartY为指针,通过一个while进行遍历矩阵

行遍历

    /*** 检查某行是否满足* @param row 一行的数组* @return 布尔值*/public static boolean checkX(int[] row){Set<Integer> set = new HashSet<>();boolean flag = true;for (int i = 0;i < row.length && flag;i++){if (0<row[i] && row[i]<10){flag = set.add(row[i]);}}return flag;}

行遍历就是一个循环将1-9的元素放入set中,通过add返回的 boolean 判断是否重复

列遍历

    /*** 判断某一列是否满足* @param x 横坐标* @param matrix 矩阵* @return 布尔值*/public static boolean checkY(int x,int[][] matrix){boolean flag = true;Set<Integer> set = new HashSet<>();for (int i = 0;i<matrix.length && flag;i++){if (0<matrix[i][x] && matrix[i][x]<10){flag = set.add(matrix[i][x]);}}return flag;}

列遍历需要我们传入一个列坐标(第几列),原理同行遍历检查的一样

总代码

public class CheckUtil {public static boolean check(int[][] matrix){boolean flag = true;flag = checkSubMatrix(matrix);System.out.println("小矩阵正常");for (int i = 0;i<matrix.length && flag;i++){flag = checkX(matrix[i]);if(!flag){break;}flag = checkY(i,matrix);}return flag;}/*** 检查某行是否满足* @param row 一行的数组* @return 布尔值*/public static boolean checkX(int[] row){Set<Integer> set = new HashSet<>();boolean flag = true;for (int i = 0;i < row.length && flag;i++){if (0<row[i] && row[i]<10){flag = set.add(row[i]);}}return flag;}/*** 判断某一列是否满足* @param x 横坐标* @param matrix 矩阵* @return 布尔值*/public static boolean checkY(int x,int[][] matrix){boolean flag = true;Set<Integer> set = new HashSet<>();for (int i = 0;i<matrix.length && flag;i++){if (0<matrix[i][x] && matrix[i][x]<10){flag = set.add(matrix[i][x]);}}return flag;}/*** 检查小矩阵内的数字* @return 布尔值*/public static boolean checkSubMatrix(int[][] matrix){boolean flag = true;int y = 0;int x = 0;while(flag&&(y<3)){int startX = 3*x;int startY = 3*y;while(flag&&(startY<3*y+3)){Set<Integer> set = new HashSet<>();if (0<matrix[startY][startX]&&matrix[startY][startX]<10){flag = set.add(matrix[startY][startX]);}startX++;if (startX>=3*x+3){startY++;startX = 3*x;}}x++;if (x>=3){y++;x=0;}}return flag;}}

测试

public class ExecuteMainn {public static void main(String[] args) {int[][] matrix = new int[][]{{4,0,1,0,0,7,2,0,0},{0,0,5,0,0,6,9,0,1},{0,6,0,0,1,4,0,0,7},{6,0,9,0,3,8,0,0,0},{0,0,0,6,0,0,0,5,8},{0,5,3,7,0,0,0,9,0},{9,1,0,0,7,0,0,0,0},{0,4,0,0,2,0,1,0,0},{0,0,0,1,0,0,0,7,3}};System.out.println(check(matrix));int y = 0;int x = 0;while(y<9){System.out.print(matrix[y][x++]+"\t");if (x>8){x=0;y++;System.out.println();}}}
}

控制台

小矩阵正常
true
4   0   1   0   0   7   2   0   0
0   0   5   0   0   6   9   0   1
0   6   0   0   1   4   0   0   7
6   0   9   0   3   8   0   0   0
0   0   0   6   0   0   0   5   8
0   5   3   7   0   0   0   9   0
9   1   0   0   7   0   0   0   0
0   4   0   0   2   0   1   0   0
0   0   0   1   0   0   0   7   3   Process finished with exit code 0

可以看到,首先进行的小矩阵判断,为真,才开始判断的行和列。【这里我没有对行列判断和小矩阵判断的复杂度分析,可以将复杂度低的先判断】。

明显可以看出打印出的矩阵是满足数独的。

编程题-判断数独是否正确相关推荐

  1. 2017网易内推编程题(判断单词):解答代码

    2019独角兽企业重金招聘Python工程师标准>>> 小易喜欢的单词具有以下特性: 1.单词每个字母都是大写字母 2.单词没有连续相等的字母 3.单词没有形如"xyxy& ...

  2. C语言如何判断数独是否正确,会数独的大佬请进。这是个判断九宫格数独是否正确的程序。...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include int matrix[9][9]; int i,j,k; int arr[9]; int index_of(int i, int a[] ...

  3. 关于python语言的编程模式、哪个说法正确_测验1: Python基本语法元素 (第1周) 单选题+程序题...

    第1章测验,共10道单选题和2道编程题,限答1次 单选题 1.Guido van Rossum正式对外发布Python版本的年份是: A.2002 B.1998 C.2008 D.1991 正确答案: ...

  4. 电子学会 2021年9月 青少年软件编程Python编程等级考试一级真题解析(选择题+判断题+编程题)

    青少年编程Python编程等级考试一级真题解析(选择题+判断题+编程题) 2021年9月 一.选择题(共25题,共50分) 取整除的运算符是?( ) A. / B. // C. ÷ D. ** 答案选 ...

  5. c语言编写程序判断图的连通,图论期末大作业编程题(如何判断一个4连通4正则图为无爪、无K4图)...

    博士期间估计这可能是唯一一个要编程的作业,搞了半天弄出这个东西,放这里为以后用到的时候查找方便. 说来也是可笑,读博士期间发现大家对上课也都没什么兴趣,老师也是那么回事,都说博士期间学的课程是要有助于 ...

  6. python 判断中文标点符号_Python入门编程题库27--生成随机密码

    一.题目 请编写程序,生成随机密码.具体要求如下: (1)使用 random 库,采用 0x1010 作为随机数种子. (2)密码 有s中的字符组成. (3)每个密码长度固定为 10 个字符. (4) ...

  7. 判断三角形java代码_java基础编程题之异常处理

    以下是刚开始学习java的基础编程题,每天持续更新java每个知识点的题目,持续练习,不断提高java基本功,培养编程能力.今天的练习的十八题是java的异常处理的使用. 1.检测年龄不能为负数和大于 ...

  8. 《去哪网编程题》表达式合法判断

    题目:[编程题] 表达式合法判断 时间限制:3秒 空间限制:32768K 写一段代码,判断一个包括'{','[','(',')',']','}'的表达式是否合法(注意看样例的合法规则.) 给定一个表达 ...

  9. 电子学会 2020年6月 青少年软件编程Python编程等级考试一级真题解析(选择题+判断题+编程题)

    青少年编程Python编程等级考试一级真题解析(选择题+判断题+编程题) 2020年6月 一.选择题(共25题,共50分) 以下哪种输入结果不可能得到以下反馈: 重要的事情说三遍:安全第一!安全第一! ...

最新文章

  1. Redhat中通过命令工具和配置文件设置TCP/IP参数的方法
  2. 谈一谈 MPU6050 姿态融合(转)
  3. 尽可能地做到无服务器,但不止于此
  4. android布局添加布局,Android中添加布局和初始化布局总结
  5. Aqua - Mac OS X平台的用户界面(user interface)
  6. js带开关的时钟_避雷器带计数器HY5WZ-17/45-JS
  7. 简约通用工作总结ppt模板
  8. jmeter需要学习的其他点
  9. 【转】解决“你没有权限访问,请与网络管理员联系”
  10. 《无人机DIY》——导读
  11. java基本数据类型转类对象
  12. 配置计算机系统doc,计算机的基本配置.doc
  13. 2018北京网络赛B题 Tomb Raider
  14. BAT程序员工作的真实情况
  15. QT项目之键盘控制光标移动
  16. C语言入门——初识C语言
  17. Ajax库-认识服务器,URL地址,axios基本用法,响应状态码,业务状态码,接口测试工具
  18. Gamemaker小实例——马里奥实现(后附资源+exe文件)
  19. 程序员健身不完全指南
  20. oracle rac 心跳参数 misscount disktimeout

热门文章

  1. No.3 说地道的美语,最简单的句子,你行吗?
  2. 英特尔链路性能预测(LPP)技术介绍 -1
  3. 1-idea社区版创建springboot项目
  4. 新零售边界的“突破”点是什么 新零售模式下新型供应链数字化系统怎么样?
  5. 签名服务器维护中,Unidbg + Web = Unidbg-server 手把手教你搭个签名服务器
  6. android 百度云测试平台,百度云测试中心为开发者提供Android 4.1云测试
  7. 登录框和操作步骤插件(大神出品)
  8. [Unity] 2D开发学习教程
  9. 声如其闻,DuerOS中的声音播放
  10. 研发实时公交车的小程序,查公交用自己的