【LeetCode】第37题——解数独(难度:困难)

  • 题目描述
  • 解题思路
  • 代码详解
  • 注意点

题目描述

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

  1. 示例:

    输入:board = [[“5”,“3”,".",".",“7”,".",".",".","."],[“6”,".",".",“1”,“9”,“5”,".",".","."],[".",“9”,“8”,".",".",".",".",“6”,"."],[“8”,".",".",".",“6”,".",".",".",“3”],[“4”,".",".",“8”,".",“3”,".",".",“1”],[“7”,".",".",".",“2”,".",".",".",“6”],[".",“6”,".",".",".",".",“2”,“8”,"."],[".",".",".",“4”,“1”,“9”,".",".",“5”],[".",".",".",".",“8”,".",".",“7”,“9”]]
    输出:[[“5”,“3”,“4”,“6”,“7”,“8”,“9”,“1”,“2”],[“6”,“7”,“2”,“1”,“9”,“5”,“3”,“4”,“8”],[“1”,“9”,“8”,“3”,“4”,“2”,“5”,“6”,“7”],[“8”,“5”,“9”,“7”,“6”,“1”,“4”,“2”,“3”],[“4”,“2”,“6”,“8”,“5”,“3”,“7”,“9”,“1”],[“7”,“1”,“3”,“9”,“2”,“4”,“8”,“5”,“6”],[“9”,“6”,“1”,“5”,“3”,“7”,“2”,“8”,“4”],[“2”,“8”,“7”,“4”,“1”,“9”,“6”,“3”,“5”],[“3”,“4”,“5”,“2”,“8”,“6”,“1”,“7”,“9”]]

解释:输入的数独如上图所示,唯一有效的解决方案如下所示:

提示:
board.length = 9
board[i].length = 9
board[i][j] 是一位数字或者 ‘.’
题目数据保证输入数独仅有一个解

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sudoku-solver
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

首先题目保证了只有一个解。方法:使用递归+回溯

先对原数组进行一次遍历,获取原数组的一些信息:
数独就是行、列、块不能有重复数字,那就设置row、col、sqr三个9×9的二维数组,[i][j]的内容代表第 i 行/列/块的数字 j+1 是否在之前出现过,如果出现置true

然后从左上角开始,对第一个为’.'的元素进行递归

递归中若遇到数字,则直接递归至下一个方块。若遇到’.'则以row、col、sqr三个数组为依据,从1~9逐个试探放入,也递归至下一个方块。若后续发现无法放入数字,则返回至上一个方块并将board回溯。

递归结束后,board被填满,直接返回即可

表述能力有限,不懂可直接看代码(别看长度长,很多都是括号占据的)

代码详解

class Solution {// 以row[i][j]为例说明:row[i][j]为true说明第i行的数字j+1出现在原数组中boolean[][] row = new boolean[9][9];boolean[][] col = new boolean[9][9];boolean[][] sqr = new boolean[9][9];public void solveSudoku(char[][] board) {// 这两层for获取原数组信息,将row、col、sqr初始化完毕for(int i = 0; i < 9; ++i) {for(int j = 0; j < 9; ++j) {if(board[i][j] != '.') {int num = board[i][j] - '0';row[i][num-1] = true;col[j][num-1] = true;sqr[i/3*3+j/3][num-1] = true;}}}// 这两个for是寻找第一个为'.'的方格,找到就递归本方块,递归完毕直接跳出循环即可for(int i = 0; i < 9; ++i) {for(int j = 0; j < 9; ++j) {if(board[i][j] == '.') {func(i, j, board);break;}}}}public boolean func(int i, int j, char[][] board) {int nexti = 0; // 下一个方块的iint nextj = 0; // 下一个方块的jif(i == -1 && j == -1) {return true; // 说明已递归完毕}if(i != 8 && j == 8) { // 列递归至末位,转到下一行的开头nexti = i + 1;nextj = 0;} else if(j != 8) { // 从左往右、从上到下遍历nexti = i;nextj = j + 1;} else if(i == 8 && j == 8) { // 最后一个方块了,置-1标记一下而已nexti = -1;nextj = -1;}if(board[i][j] != '.') {return func(nexti, nextj, board); // 是数字就递归至下一个方块} else {for(int n = 1; n <= 9; ++n) { // 不是数字的话就将1~9试探性放入,并以row、col、sqr为依据if(row[i][n-1] || col[j][n-1] || sqr[i/3*3+j/3][n-1]) {continue; // 当前数字已出现过,试探下一个数字} else {// 若当前数字未出现过,试探性放入board[i][j] = (char)('0' + n);row[i][n-1] = true;col[j][n-1] = true;sqr[i/3*3+j/3][n-1] = true;if(!func(nexti, nextj, board)) { // 递归不顺就还原/回溯board[i][j] = '.';row[i][n-1] = false;col[j][n-1] = false;sqr[i/3*3+j/3][n-1] = false;} else {return true; // 递归顺利就返回true}}}return false; // 若运行至此说明1~9都无法放入,说明前面有数字放错了,需要回溯至前一个方块,前一个方块的数字会继续试探下去}}
}

注意点

  • 不要忘记回溯(就像是用铅笔填数独时,填错了要擦除一样)

【LeetCode】第37题——解数独(难度:困难)相关推荐

  1. LeetCode—37. 解数独(困难)

    37. 解数独(困难) 题目描述: 编写一个程序,通过填充空格来解决数独问题. 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 ...

  2. Leetcode 37:解数独(超详细的解法!!!)

    编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实线分隔的 3x3 ...

  3. Leetcode每日一题:37.sudoku-solver(解数独)

    得用到DFS,一条路走到黑: 做这道题得时候一直在想 如何在line / 9 == 1的时候直接返回呢 开始准备用goto 后来改变主意设一个flag就行了 bool flag = false; bo ...

  4. [LeetCode]高频算法题

    建议在准备面试前的1-2周过一遍,这里尽量用简短的几个词,记录每道题的核心解法,帮助记忆 怎么用这个文档: 1)如果你还有1-2个月开始面试,那就跟着这个文档一道一道的写吧,看看里面说的解法是否符合你 ...

  5. LeetCode高频题37. 解数独

    LeetCode高频题37. 解数独 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目 互联网大厂们在公司养了一大批ACM竞赛的 ...

  6. 代码随想录刷题|LeetCode 332.重新安排行程 51. N皇后 37. 解数独

    目录 332.重新安排行程 思路 重新安排行程 51. N皇后 思路 N皇后 37. 解数独 思路 解数独         这三道题目都是困难题目,都是根据代码随想录的思路总结书写,慢慢理解,慢慢熟练 ...

  7. Leetcode困难笔记 37.解数独

    解数独,回溯法即可.从左到右,从上到下,检查每种数字是否可以放进格子,如果可以就放入,一直搜索直到解数独完成. class Solution{public:bool finish = false;bo ...

  8. LeetCode 36有效的数独37解数独(八皇后问题)

    公众号:bigsai 回复进群加入打卡 有效的数独 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列 ...

  9. LintCode 802. 数独(回溯)/ LeetCode 37. 解数独

    1. 题目 编写一个程序,通过填充空单元来解决数独难题. 空单元由数字0表示. 你可以认为只有一个唯一的解决方案. LeetCode 37 题类似,把 int 改成 char,注意转换 2. 解题 行 ...

最新文章

  1. Selenium IDE使用
  2. DedeCms 5.7后台去除版权及去除广告的方法
  3. 原生JS封装Ajax插件(同域jsonp跨域)
  4. 对齐方式有那些_字节对齐不慎引发的挂死问题
  5. python计算机视觉编程调试问题
  6. python import 类 继承_python学习之类的继承
  7. react学习(62)--注意数据格式返回
  8. DVA框架统一处理所有页面的loading状态
  9. JS模块化编程require.js简介
  10. 图元和片元_OpenGL渲染流水线中顶点(vertexs) 图元(primitives) 片元(fragments片断) 像素(pixels)的含义...
  11. RESTful Webservice 和 SOAP Webserivce 对比及区别
  12. 白鹭引擎和layabox哪个好用,哪个技术更成熟 ?
  13. 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第3节 综合案例_文件上传_5_综合案例_文件上传案例优化...
  14. 读取Flash w25x64未响应 导致卡死的问题
  15. 什么是软件安全性测试?安全测试有哪些测试方法和手段
  16. ztree学习笔记(一)
  17. 分支定界法求解旅行商问题
  18. vob文件怎么转换成mp4?
  19. loj 1224 - DNA Prefix
  20. Harbor镜像库搭建以及如何在idea上构建镜像并推送Harbor

热门文章

  1. 利用python3 requests和BeautifulSoup4抓取百度贴吧研究生录取通知书并展示
  2. 基于STM32的Lora无线抄表系统
  3. 迅雷,快车,旋风地址转换器
  4. html css 开发商业站点,《使用HTML语言和CSS开发商业站点》
  5. N76E003的中断向量函数
  6. 冬至日当天,北京时间早上9点,潍坊地区高度100米的楼的影子长度是多少?请列出详细的计算过程...
  7. SAP MDG —— 与ERP间的配置Customizing同步
  8. pycharm怎么把中文翻译成英文
  9. 天融信防火墙基础配置步骤
  10. 个人博客的APlayer音乐播放器