LeetCode: Sudoku Solver (数独求解)

采用backtracking求解:首先找到一个需要求解的位置,对这个位置尝试求解,如果求解成功则返回,否则恢复这个位置之前的状态,退回一部,尝试其他数字。递归地调用这个过程进行求解。

Java Code:

public class Solution {
  public void solveSudoku(char[][] board) {
    // Start typing your Java solution below
    // DO NOT write main() function
    solveSudoku(board, 0, 0);
  }

  private boolean solveSudoku(char[][] board, int i, int j) {
    int[] position = findPosition(board, i, j);
    if (position == null) {
      return true;
    } else {
      i = position[0];
      j = position[1];
    }
    for (int num = 1; num <= 9; num++) {
      board[i][j] = Character.forDigit(num, 10);
      if (checkValidity(board, i, j)) {
        if (solveSudoku(board, i, j)) {
          return true;
        }
      }
    }
    board[i][j] = '.';
    return false;
  }

  private int[] findPosition(char[][] board, int i, int j) {
    int ii = i;
    int jj = j;
    for (; ii < board.length; ii++) {
      if (ii == i) {
        jj = j;
      } else {
        jj = 0;
      }
      for (; jj < board[ii].length; jj++) {
        char c = board[ii][jj];
        if (!Character.isDigit(c)) {
          return new int[]{ii, jj};
        }
      }
    }
    return null;
  }

  private boolean checkValidity(char[][] board, int i, int j) {
    boolean[] a = new boolean[board.length];
    java.util.Arrays.fill(a, false);
    for (int x = 0; x < board[i].length; x++) {
      char c = board[i][x];
      if (Character.isDigit(c)) {
        if (a[c - '0' - 1] == false) {
          a[c - '0' - 1] = true;
        } else {
          return false;
        }
      }
    }
    java.util.Arrays.fill(a, false);
    for (int y = 0; y < board.length; y++) {
      char c = board[y][j];
      if (Character.isDigit(c)) {
        if (a[c - '0' - 1] == false) {
          a[c - '0' - 1] = true;
        } else {
          return false;
        }
      }
    }
    java.util.Arrays.fill(a, false);
    int x = 0;
    int y = 0;
    if (i < 3) {
      x = 0;
    } else if (i < 6) {
      x = 3;
    } else {
      x = 6;
    }
    if (j < 3) {
      y = 0;
    } else if (j < 6) {
      y = 3;
    } else {
      y = 6;
    }
    int xx = x;
    int yy = y;
    int xBound = x + 3;
    int yBound = y + 3;
    for (x = xx; x < xBound; x++) {
      for (y = yy; y < yBound; y++) {        
        char c = board[x][y];
        if (Character.isDigit(c)) {
          if (a[c - '0' - 1] == false) {
            a[c - '0' - 1] = true;
          } else {
            return false;
          }
        }
      }
    }
    return true;
  }

  public void test() {
    char[][] board = {{'.','.','9','7','4','8','.','.','.'},
                      {'7','.','.','.','.','.','.','.','.'},
                      {'.','2','.','1','.','9','.','.','.'},
                      {'.','.','7','.','.','.','2','4','.'},
                      {'.','6','4','.','1','.','5','9','.'},
                      {'.','9','8','.','.','.','3','.','.'},
                      {'.','.','.','8','.','3','.','2','.'},
                      {'.','.','.','.','.','.','.','.','6'},
                      {'.','.','.','2','7','5','9','.','.'}};
    solveSudoku(board);
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
        System.out.print(board[i][j] + " ");
      }
      System.out.println();
    }
  }

  public static void main(String[] args) {
    new Solution().test();
  }
}


你可能感兴趣的:(LeetCode: Sudoku Solver (数独求解))