37. 解数独

ゝ一世哀愁。 2024-03-30 12:35 184阅读 0赞

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] 是一位数字或者 ‘.’
题目数据 保证 输入数独仅有一个解

思路:(回溯)

  • 由于题目有三个条件,所以应该存储每个条件的数字使用情况;
  • 遍历数字,只有在三个条件中都未使用的时,将该数暂存到该位置:

    • 如果在以上数字条件下,下面的位置都能找到合适的数字,则成立;
    • 如果在上述数字条件下,下面的位置遍历1-9,都不能找到合适的数字,则返回false,回溯上一步结果,上一步继续往后遍历,直到9,如果找不到继续回溯;

本题关键:
将 backtracking 函数的返回类型设为 boolean 类型,如果下一次迭代返回结果为 true,则填入数字正确,否则才数字不正确,回溯,继续遍历剩余数字:

  1. bod[r][c] = (char)(num + '0');
  2. rowsUsed[r][num] = colsUsed[c][num] = cubesUsed[cubeNum(r, c)][num] = true;
  3. if(backtracking(nr , nc)) {
  4. return true;
  5. }else {//不成立回溯
  6. bod[r][c] = '.';
  7. rowsUsed[r][num] = colsUsed[c][num] = cubesUsed[cubeNum(r, c)][num] = false;
  8. continue;
  9. }

代码:(Java)

  1. public class sudoku {
  2. public static void main(String[] args) {
  3. //TODO Auto-generated method stub
  4. char [][] board = {
  5. {
  6. '5', '3', '.', '.', '7', '.', '.', '.', '.'},
  7. {
  8. '6', '.', '.', '1', '9', '5', '.', '.', '.'},
  9. {
  10. '.', '9', '8', '.', '.', '.', '.', '6', '.'},
  11. {
  12. '8', '.', '.', '.', '6', '.', '.', '.', '3'},
  13. {
  14. '4', '.', '.', '8', '.', '3', '.', '.', '1'},
  15. {
  16. '7', '.', '.', '.', '2', '.', '.', '.', '6'},
  17. {
  18. '.', '6', '.', '.', '.', '.', '2', '8', '.'},
  19. {
  20. '.', '.', '.', '4', '1', '9', '.', '.', '5'},
  21. {
  22. '.', '.', '.', '.', '8', '.', '.', '7', '9'}
  23. };
  24. solveSudoku(board);
  25. for(int i = 0; i < 9; i++) {
  26. for(int j = 0; j < 9; j++) {
  27. System.out.print(board[i][j]+ " ");
  28. }
  29. System.out.println();
  30. }
  31. }
  32. private static boolean[][] rowsUsed = new boolean[9][10];
  33. private static boolean[][] colsUsed = new boolean[9][10];
  34. private static boolean[][] cubesUsed = new boolean[9][10];
  35. private static char[][] bod;
  36. public static void solveSudoku(char[][] board) {
  37. bod = board;
  38. for(int r = 0; r < 9; r++) {
  39. for(int c = 0; c < 9; c++) {
  40. if(bod[r][c] != '.') {
  41. int num = Character.getNumericValue(bod[r][c]);
  42. rowsUsed[r][num] = true;
  43. colsUsed[c][num] = true;
  44. cubesUsed[cubeNum(r, c)][num] = true;
  45. }
  46. }
  47. }
  48. backtracking(0, 0);
  49. }
  50. private static boolean backtracking(int r, int c) {
  51. // TODO Auto-generated method stub
  52. if(r == 9) {
  53. return true;
  54. }
  55. int nr, nc;
  56. if(c == 8) {
  57. nr = r + 1;
  58. nc = 0;
  59. }else {
  60. nr = r;
  61. nc = c + 1;
  62. }
  63. if(bod[r][c] != '.') {
  64. return backtracking(nr , nc);
  65. }
  66. for(int num = 1; num <= 9; num++) {
  67. if(rowsUsed[r][num] || colsUsed[c][num] || cubesUsed[cubeNum(r, c)][num]) {
  68. continue;
  69. }
  70. bod[r][c] = (char)(num + '0');
  71. rowsUsed[r][num] = colsUsed[c][num] = cubesUsed[cubeNum(r, c)][num] = true;
  72. if(backtracking(nr , nc)) {
  73. //判断条件为递归结果
  74. return true;
  75. }else {
  76. //不成立回溯
  77. bod[r][c] = '.';
  78. rowsUsed[r][num] = colsUsed[c][num] = cubesUsed[cubeNum(r, c)][num] = false;
  79. continue;
  80. }
  81. }
  82. return false;
  83. }
  84. private static int cubeNum(int i, int j) {
  85. //返回第几个方块
  86. // TODO Auto-generated method stub
  87. int r = i / 3;
  88. int c = j / 3;
  89. return r * 3 + c;
  90. }
  91. }
运行结果:

在这里插入图片描述

注:仅供学习参考!

题目来源:力扣.

发表评论

表情:
评论列表 (有 0 条评论,184人围观)

还没有评论,来说两句吧...

相关阅读

    相关 37. 解数

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

    相关 LeetCode37-解数

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

    相关 【LeetCode 37解数

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

    相关 37. 解数

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

    相关 37解数

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