Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.

A sudoku puzzle...

...and its solution numbers marked in red.

Hide Tags

Backtracking Hash Table

 

    这题是解数独,这个嘛,我用的是递归写法,简单描述就是填写当前空格,递归下一格,遇到不行返回,不过逻辑写的不好,很多奇奇怪怪的细节的判断。
 
算法逻辑:
  1. 创建一个辅助函数,help(vector<vector<char> > & board,int i,int ii,int j,int jj),其中i为第几行,j 第几列,ii 小框中的第几行,jj 小框中第几列。
  2. help 函数4层for 循环遍历整个9*9 矩阵,说是4层,跟两次for 是一样的,i 和j 的步长是3,for(;i<9;i+=3),因为这4个变量的初始化在函数传入的时候,所以在其循环结束时候尾部赋0,其中一个不好的地方。
  3. 4层循环内部,首先判断当前格board[i+ii][j+jj]是否为数字,不然继续循环。
  4. 创建标记finish = false,标记接下来的填入(当前格为空)能否完成整个矩阵,用于控制跳出填写,和如果填写失败修复当前格为'.' 回溯。
  5. 遍历1-9 尝试填写,需要用到bool canIn=true,判断行,列,框中的情况,如果通过判断则修改当框为遍历的数字,递归下一格,输入当前格的i ii j jj,便可以,这是第二个不好的地方,判断没有写为外部函数,另外函数的参数设置导致了很多细节问题。
  6. 下层返回的值赋予 finish ,如果为false ,表示当前填写不行,继续遍历,如果为true,跳出填写的遍历。
  7. 结束遍历后判断是否已经填写整个矩阵,如果finish 为false,表示失败了,则当前格,然后返回false,成功先别返回。
  8. 外部4层循环结束返回true。

   所以在外层循环后返回true,是假如例子上的情况,最后一个格不为空,那么按上面逻辑是不会进入内部的,而如果能够全部遍历完整个矩阵,那么表示没有在内部返回,等价于成功填写了。

之所以使用 ii jj,是为了可以方便处理3*3框,在能否填写的时候,需要注意跳过自身与自身判断,先判断行列,然后框的时候变可以跳过当前框所在的行列了。

  1. #include <vector>
  2. #include <iostream>
  3. #include <iterator>
  4. using namespace std;
  5.  
  6. class Solution {
  7. public:
  8. void solveSudoku(vector<vector<char> > &board) {
  9. help(board,,,,);
  10. }
  11. bool help(vector<vector<char> > & board,int i,int ii,int j,int jj){
  12. for(;i<;i+=){
  13. for(;ii<;ii++){
  14. for(;j<;j+=){
  15. for(;jj<;jj++){
  16. if(board[i+ii][j+jj]!='.') continue;
  17. bool finish = false;
  18. for(char c='';c<=''&&!finish;c++){
  19. bool canIn= true;
  20. for(int k=;k<&&canIn;k++){
  21. if(k!=i+ii&&board[k][j+jj]==c) canIn = false;
  22. if(k!=j+jj&&board[i+ii][k]==c) canIn = false;
  23. }
  24. for(int ti=;ti<&&canIn;ti++){
  25. if(ti == ii) continue;
  26. for(int tj=;tj<&&canIn;tj++){
  27. if(tj==jj) continue;
  28. if(board[ti+i][tj+j]==c) canIn = false;
  29. }
  30. }
  31. if(canIn==false) continue;
  32. board[i+ii][j+jj] = c;
  33. finish = help(board,i,ii,j,jj);
  34. }
  35. if(!finish){ board[i+ii][j+jj] = '.'; return false; }
  36. }
  37. jj = ;
  38. }
  39. j=;
  40. }
  41. ii=;
  42. }
  43. return true;
  44. }
  45. };
  46.  
  47. int main()
  48. {
  49. vector<char> line;
  50. vector<vector<char> > board;
  51. line = {'','','.','.','','.','.','.','.'};
  52. board.push_back(line);
  53. line.clear();
  54. line = {'','.','.','','','','.','.','.'};
  55. board.push_back(line);
  56. line.clear();
  57. line = {'.','','','.','.','.','.','','.'};
  58. board.push_back(line);
  59. line.clear();
  60. line = {'','.','.','.','','.','.','.',''};
  61. board.push_back(line);
  62. line.clear();
  63. line = {'','.','.','','.','','.','.',''};
  64. board.push_back(line);
  65. line.clear();
  66. line = {'','.','.','.','','.','.','.',''};
  67. board.push_back(line);
  68. line.clear();
  69. line = {'.','','.','.','.','.','','','.'};
  70. board.push_back(line);
  71. line.clear();
  72. line = {'.','.','.','','','','.','.',''};
  73. board.push_back(line);
  74. line.clear();
  75. line = {'.','.','.','.','','.','.','',''};
  76. board.push_back(line);
  77. Solution sol;
  78. sol.solveSudoku(board);
  79. for(int i=;i<board.size();i++){
  80. copy(board[i].begin(),board[i].end(),ostream_iterator<char>(cout," "));
  81. cout<<endl;
  82. }
  83. return ;
  84. }
 
 
 
 
 
 
 
 
 

[LeetCode] Sudoku Solver 解数独,递归,回溯的更多相关文章

  1. [leetcode]37. Sudoku Solver 解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  2. [LeetCode] Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  3. 037 Sudoku Solver 解数独

    写一个程序通过填充空格来解决数独.空格用 '.' 表示. 详见:https://leetcode.com/problems/sudoku-solver/description/ class Solut ...

  4. LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)

    Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku bo ...

  5. Sudoku Solver, 求数独

    问题描述:填充数独表中空元素.空元素为'.' 算法分析:没填充一个数,都要看这个数所在的行,列,小矩阵是否合法.然后还要看整个数独表是否正确,而判断整个数独表只能通过递归,因为前一个结果的判断要依赖后 ...

  6. [LeetCode] 37. Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  7. LeetCode OJ:Sudoku Solver(数独游戏)

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  8. Leetcode: Sudoku Solver

    July 19, 2015 Problem statement: Write a program to solve a Sudoku puzzle by filling the empty cells ...

  9. [LeetCode] Sudoku Solver(迭代)

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

随机推荐

  1. MySQL解决中文编码问题

    转载组员博客 地址:MySQL解决中文编码问题

  2. yum仓库及配置

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 最近由于服务器需求,需要在公司内网搭建内网yum源. 搭建内网yum源需要分以下几个步骤,如下: 1. yum是什么 2. repo文件是什么 3. r ...

  3. JavaScript 循环

    for循环:  如果您希望一遍又一遍运行相同的代码,并且每次的值都不同,那么使用循环是很方便的. 我们可以这样输出数组的值: document.write(cars[0] + "<br ...

  4. Ecshop之ajax修改表里的状态(函数化处理)

    目录 功能: 效果: 思路: 页面里 控制器里 功能: `点击图片,修改表里的状态值` 效果: 思路: 页面里在img里点绑定onclick件事,调用js函数listTable.toggle oncl ...

  5. (洛谷)P1019 单词接龙

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙" ...

  6. HDU1272小希的迷宫

    小希的迷宫 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一 ...

  7. 用私有构造器或者枚举类型强化Singleton属性

    1.Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,如窗口管理器或者文件系统.使类称为Singleton会使它的客户端调试变的十分困难,因为无法给S ...

  8. MySQL之Schema与数据类型优化

    选择优化的数据类型 MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要.不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择: 更小的通常更好一般情况下,应该尽量使用 ...

  9. 【Word Search】cpp

    题目: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed fr ...

  10. 【3Sum】cpp

    题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find al ...