【LeetCode】第37题——解数独(难度:困难)
【LeetCode】第37题——解数独(难度:困难)
- 题目描述
- 解题思路
- 代码详解
- 注意点
题目描述
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
- 数字 1-9 在每一行只能出现一次。
- 数字 1-9 在每一列只能出现一次。
- 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
- 示例:
输入: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题——解数独(难度:困难)相关推荐
- LeetCode—37. 解数独(困难)
37. 解数独(困难) 题目描述: 编写一个程序,通过填充空格来解决数独问题. 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 ...
- Leetcode 37:解数独(超详细的解法!!!)
编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以粗实线分隔的 3x3 ...
- Leetcode每日一题:37.sudoku-solver(解数独)
得用到DFS,一条路走到黑: 做这道题得时候一直在想 如何在line / 9 == 1的时候直接返回呢 开始准备用goto 后来改变主意设一个flag就行了 bool flag = false; bo ...
- [LeetCode]高频算法题
建议在准备面试前的1-2周过一遍,这里尽量用简短的几个词,记录每道题的核心解法,帮助记忆 怎么用这个文档: 1)如果你还有1-2个月开始面试,那就跟着这个文档一道一道的写吧,看看里面说的解法是否符合你 ...
- LeetCode高频题37. 解数独
LeetCode高频题37. 解数独 提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目 互联网大厂们在公司养了一大批ACM竞赛的 ...
- 代码随想录刷题|LeetCode 332.重新安排行程 51. N皇后 37. 解数独
目录 332.重新安排行程 思路 重新安排行程 51. N皇后 思路 N皇后 37. 解数独 思路 解数独 这三道题目都是困难题目,都是根据代码随想录的思路总结书写,慢慢理解,慢慢熟练 ...
- Leetcode困难笔记 37.解数独
解数独,回溯法即可.从左到右,从上到下,检查每种数字是否可以放进格子,如果可以就放入,一直搜索直到解数独完成. class Solution{public:bool finish = false;bo ...
- LeetCode 36有效的数独37解数独(八皇后问题)
公众号:bigsai 回复进群加入打卡 有效的数独 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列 ...
- LintCode 802. 数独(回溯)/ LeetCode 37. 解数独
1. 题目 编写一个程序,通过填充空单元来解决数独难题. 空单元由数字0表示. 你可以认为只有一个唯一的解决方案. LeetCode 37 题类似,把 int 改成 char,注意转换 2. 解题 行 ...
最新文章
- Selenium IDE使用
- DedeCms 5.7后台去除版权及去除广告的方法
- 原生JS封装Ajax插件(同域jsonp跨域)
- 对齐方式有那些_字节对齐不慎引发的挂死问题
- python计算机视觉编程调试问题
- python import 类 继承_python学习之类的继承
- react学习(62)--注意数据格式返回
- DVA框架统一处理所有页面的loading状态
- JS模块化编程require.js简介
- 图元和片元_OpenGL渲染流水线中顶点(vertexs) 图元(primitives) 片元(fragments片断) 像素(pixels)的含义...
- RESTful Webservice 和 SOAP Webserivce 对比及区别
- 白鹭引擎和layabox哪个好用,哪个技术更成熟 ?
- 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第3节 综合案例_文件上传_5_综合案例_文件上传案例优化...
- 读取Flash w25x64未响应 导致卡死的问题
- 什么是软件安全性测试?安全测试有哪些测试方法和手段
- ztree学习笔记(一)
- 分支定界法求解旅行商问题
- vob文件怎么转换成mp4?
- loj 1224 - DNA Prefix
- Harbor镜像库搭建以及如何在idea上构建镜像并推送Harbor
热门文章
- 利用python3 requests和BeautifulSoup4抓取百度贴吧研究生录取通知书并展示
- 基于STM32的Lora无线抄表系统
- 迅雷,快车,旋风地址转换器
- html css 开发商业站点,《使用HTML语言和CSS开发商业站点》
- N76E003的中断向量函数
- 冬至日当天,北京时间早上9点,潍坊地区高度100米的楼的影子长度是多少?请列出详细的计算过程...
- SAP MDG —— 与ERP间的配置Customizing同步
- pycharm怎么把中文翻译成英文
- 天融信防火墙基础配置步骤
- 个人博客的APlayer音乐播放器