Sudoku Solver

Share my LeetCode answer


37. Sudoku Solver

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.

sudoku

The solution is: sudoku_solved

Code

class Solution {
    public void solveSudoku(char[][] board) {
        if (board == null || board.length == 0) return;
        doSolve(board, 0, 0);
    }
    
    public boolean doSolve(char[][] board, int row, int col) {
        /*
        Solve the problem using backtracking, do it recursively.
        Input:
            board : the board matrix
            row   : start row
            col   : start col
        Output:
            a boolean value specifiy whether the problem is solved
        */
        for (int i = row; i < 9; i++, col=0) {
            for (int j = col; j < 9; j++) {
                if (board[i][j] == '.') {
                    for (char num = '1'; num <= '9'; num++) { //解空间,从1到9的数
                        if (isValid(board, i, j, num)) {
                            board[i][j] = num;      //依次尝试解空间
                            if (doSolve(board, i, j+1)) return true; //递归找到最优解
                            else board[i][j] = '.';    //回溯
                        }
                    } 
                    //解空间遍历结束,未找到最优解
                    return false;
                }
            }
        }
        return true;
    }
    
    public boolean isValid(char[][] board, int row, int col, char c) {
        //检查在矩阵的某一位加一个元素之后是否有效
        int rowIndex = 3 * (row/3) colIndex = 3 * (col/3); //在3*3的块中行列的索引
        for (int i = 0; i < 9; i++) {
            if (board[row][i] == c) return false;  //检查当前行
            if (board[i][col] == c) return false;  //检查当前列
            if (board[rowIndex+i/3][colIndex+i%3] == c) return false;  //检查3*3的块
        }
        return true;
    }
}

解题思路

  • 使用回溯法解题,思路如下

      public void main(char[][] board){
          doSolve(board, 0, 0)  // 调用doSolve递归解题
      }
    	
      public boolean doSolve(char[][] board, int row, int col) {
          isValid(board, i, j, num) // 尝试解空间的一个元素,检查是否有效
              board[i][j] = num;   // 尝试num
              doSolve(board, i, j+1)  // 递归求得最优解
                   return true
              board[i][j] = '.'  // 回溯
      }
    	
      public boolean isValid(char[][] board, int row, int col, char c) {
          int rowIndex = 3*(row/3)
          int colIndex = 3*(col/3)
          for (i = 0 : 9) {
              //check row
              //check col
              //check block	
          }
          return true;
      }
    
  • 递归时,尝试从‘1’到‘9’的所有元素,检查是否有效,然后放入之后调用递归,递归结束回溯。