题目

类型:回溯

难度:困难

解数独 - 图1

解题思路

尝试填充,如果发现重复了,那么擦除重新进行新一轮的尝试,直到把整个数组填充完成。

1、数独首先行,列,还有 3*3 的方格内数字是 1~9 不能重复。

2、声明布尔数组,表明行列中某个数字是否被使用了, 被用过视为 true,没用过为 false。

3、初始化布尔数组,表明哪些数字已经被使用过了。

4、尝试去填充数组,只要行,列, 还有 3*3 的方格内 出现已经被使用过的数字,我们就不填充,否则尝试填充。

5、如果填充失败,那么我们需要回溯。将原来尝试填充的地方改回来。

递归直到数独被填充完成。

代码

  1. class Solution {
  2. public void solveSudoku(char[][] board) {
  3. // 三个布尔数组 表明 行, 列, 还有 3*3 的方格的数字是否被使用过
  4. boolean[][] rowUsed = new boolean[9][10];
  5. boolean[][] colUsed = new boolean[9][10];
  6. boolean[][][] boxUsed = new boolean[3][3][10];
  7. // 初始化
  8. for(int row = 0; row < board.length; row++){
  9. for(int col = 0; col < board[0].length; col++) {
  10. int num = board[row][col] - '0';
  11. if(1 <= num && num <= 9){
  12. rowUsed[row][num] = true;
  13. colUsed[col][num] = true;
  14. boxUsed[row/3][col/3][num] = true;
  15. }
  16. }
  17. }
  18. // 递归尝试填充数组
  19. recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, 0, 0);
  20. }
  21. private boolean recusiveSolveSudoku(char[][]board, boolean[][]rowUsed, boolean[][]colUsed, boolean[][][]boxUsed, int row, int col){
  22. // 边界校验, 如果已经填充完成, 返回true, 表示一切结束
  23. if(col == board[0].length){
  24. col = 0;
  25. row++;
  26. if(row == board.length){
  27. return true;
  28. }
  29. }
  30. // 是空则尝试填充, 否则跳过继续尝试填充下一个位置
  31. if(board[row][col] == '.') {
  32. // 尝试填充1~9
  33. for(int num = 1; num <= 9; num++){
  34. boolean canUsed = !(rowUsed[row][num] || colUsed[col][num] || boxUsed[row/3][col/3][num]);
  35. if(canUsed){
  36. rowUsed[row][num] = true;
  37. colUsed[col][num] = true;
  38. boxUsed[row/3][col/3][num] = true;
  39. board[row][col] = (char)('0' + num);
  40. if(recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, row, col + 1)){
  41. return true;
  42. }
  43. board[row][col] = '.';
  44. rowUsed[row][num] = false;
  45. colUsed[col][num] = false;
  46. boxUsed[row/3][col/3][num] = false;
  47. }
  48. }
  49. } else {
  50. return recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, row, col + 1);
  51. }
  52. return false;
  53. }
  54. }