一、题目描述

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

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

数字 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] 是一位数字或者 ‘.’ 需要我们填的空 就是 “.”
题目数据 保证 输入数独仅有一个解

二、题目分析&解题思路

我们先看一下如何来逐个填入数字并判断数字是否合理

那我们先写出来判断数字在每一行、每一列、每一个九宫格里是否重复

bool isValid(int row, int col, char val, vector<vector<char>>& board)
{// 判断行里是否重复for (int i = 0; i < 9; i++) { if (board[row][i] == val) {return false;}}// 判断列里是否重复for (int j = 0; j < 9; j++) { if (board[j][col] == val) {return false;}}// 判断9方格里是否重复int startRow = (row / 3) * 3;//计算每一个九宫格起始的行和列int startCol = (col / 3) * 3;for (int i = startRow; i < startRow + 3; i++) { for (int j = startCol; j < startCol + 3; j++) {if (board[i][j] == val ) {return false;}}}//都不重复代表这个位置可以填该数字return true;
}

每一个数字如何判断的代码已经写好了,那么接下来如何去填数字,才能把所有的情况都试一遍呢?
那就是所有 需要填数字的位置都得遍历一遍,而且每一个位置都需要从 1~ 9 都试一遍
那么代码来了:

    for (int i = 0; i < board.size(); i++) // 遍历行{        for (int j = 0; j < board[0].size(); j++) // 遍历列{ if (board[i][j] == '.') //该位置为空,需要我们填数字{for (char k = '1'; k <= '9'; k++) //从 1 ~ 9 都逐个试{     if (isValid(i, j, k, board)) // (i, j) 判断 k是否 可以放这个位置{board[i][j] = k;                // 放置k}}return false;  // 9个数都试完了,都不行,那么就返回false }                }}return true;

这样对吗?显然不对,这样只能得出来一组结果,无论成功与否都只看这一把了,属实离谱
例如这里,第一行第三列 除了填 1 还可以 填 2 、4

那么从该位置起 一共需要 循环 3 次,得到 3 个 9 × 9 结果(x 代表填入得数字,示例)

如果 其中每个 格子 1 - 9 都试过了都不行返回false,如果其中有一组适合则return true
而每一组得结果只需要一直递归下去即可,并且每个位置得每一个数字试完之后记得回溯,也就是试下一组数字

                    if (isValid(i, j, k, board)) {board[i][j] = k;                // 放置kif (backtracking(board)) //递归试每个位置的每一个数字{return true// 如果找到合适一组立刻返回}; board[i][j] = '.';              // 回溯,撤销k,接下来试下一个数字}

三、代码实现

class Solution {private:
bool backtracking(vector<vector<char>>& board)
{for (int i = 0; i < board.size(); i++) // 遍历行{        for (int j = 0; j < board[0].size(); j++) // 遍历列{ if (board[i][j] == '.') {for (char k = '1'; k <= '9'; k++) {     if (isValid(i, j, k, board)) // (i, j) 这个位置放k是否合适{board[i][j] = k;  // 放置kif (backtracking(board)) //递归填每种情况的接下来每一个数字{return true;// 如果找到合适一组立刻返回} board[i][j] = '.';  // 回溯,撤销k,接下来试下一个数字}}return false;  // 9个数都试完了,都不行,那么就返回false }                }}return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
}
bool isValid(int row, int col, char val, vector<vector<char>>& board) {// 判断行里是否重复for (int i = 0; i < 9; i++) { if (board[row][i] == val) {return false;}}// 判断列里是否重复for (int j = 0; j < 9; j++) {if (board[j][col] == val) {return false;}}// 判断9方格里是否重复int startRow = (row / 3) * 3;//计算每个3×3 宫格的起始行、列int startCol = (col / 3) * 3;for (int i = startRow; i < startRow + 3; i++) { for (int j = startCol; j < startCol + 3; j++) {if (board[i][j] == val ) {return false;}}}return true;
}
public:void solveSudoku(vector<vector<char>>& board) {backtracking(board);}
};

运行结果:

LeetCode 37. 解数独相关推荐

  1. Java实现 LeetCode 37 解数独

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

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

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

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

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

  4. leetcode 37. 解数独 思考分析

    目录 题目 核心思路的不断细化 1.核心框架 2.考虑到每个位置的工作 3.考虑到到达最后一列.该位置的数已经预置的情况 4.判断是否符合规则的函数 5.确定递归终止条件+确定函数返回值 AC代码 题 ...

  5. LeetCode 37 解数独

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

  6. LeetCode 37. 解数独 Sudoku Solver

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

  7. 递归生成数独java_[leetcode] 37. 解数独(Java)(dfs,递归,回溯)

    1A 这个题其实15分钟左右就敲出来并且对了...但是由于我输错了一个数..导致我白白debug一个多小时.. 没啥难度,练递归-dfs的好题 class Solution { private int ...

  8. Leetcode算法Java全解答--37. 解数独

    Leetcode算法Java全解答–37. 解数独 文章目录 Leetcode算法Java全解答--37. 解数独 题目 想法 结果 总结 代码 我的答案 大佬们的答案 测试用例 其他 题目 编写一个 ...

  9. LeetCode高频题37. 解数独

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

最新文章

  1. Linux下编辑器vi/vim的使用介绍
  2. cassandra框架模型之一——Colum排序,分区策略 Token,Partitioner bloom-filter,HASH
  3. Java 集合系列(三)Collection 接口
  4. 爬虫---Beautiful Soup 通过添加不同的IP请求
  5. 多久能学会前端?怎么学?
  6. 官方回应 ,清华大学对于造假的处理结果来了:一作撤销博士学位,导师停止招生资格及提前退休...
  7. SELinux系列(十七)—awk命令使用详解
  8. 移动前端自适应适配布局解决方案
  9. HDFS 透明加密使用、Keystore和Hadoop KMS、加密区域、透明加密关键概念和架构、KMS配置
  10. 键盘按钮KeyCode使用案例
  11. 倡议书格式范文_倡议书的格式及范文
  12. 乖离性百万亚瑟王服务器维护,重大更新!《乖离性百万亚瑟王》10月23日维护更新公告...
  13. 数据导入与预处理——1.初步熟悉kettle-Spoon
  14. 智能音箱音效哪个好_四大智能音箱,你觉得哪个才是最好用的?
  15. 九宫格一条线连起来_9个圆圈用4条线连起来-九个点用四条线连接-数学-霍甲心同学...
  16. 服务器怎么建ip网站,云服务器搭建网站ip
  17. 软考程序员大纲2004
  18. ebuy遇到的问题以及解决方法
  19. 知识付费直播使用https方法 教程
  20. 基于本地存储LVM新建虚机方案

热门文章

  1. 凸包算法理解——基于MATLAB代码
  2. 前端 苹果safari 兼容性问题
  3. android R Variable Refresh Rate 可变帧率 VRR
  4. C++之new动态分配内存生成数组
  5. 2018MODIS数据最新下载方法-简单实用
  6. 七、Kafka版本的选择
  7. 有趣的对比:Apple与Amazon的财报与股票表现
  8. 中冠百年|成为有钱人的六个步骤
  9. 新概念英语1册83课
  10. 静态全局变量和全局变量