int n = 3; int N = n * n; //分别代表每一行、列、方块中0-9填写的数字出现的次数 int [][] rows = newint[N][N + 1]; int [][] columns = newint[N][N + 1]; int [][] boxes = newint[N][N + 1];
publicvoidsolveSudoku(char[][] board){ this.board = board; // 初始化 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { char num = board[i][j]; if (num != '.') { int d = Character.getNumericValue(num); placeNumber(d, i, j); } } } backtrack(0, 0); }
publicbooleancouldPlace(int d, int row, int col){ /* * 检查该位置是否能放数字 */ int idx = (row / n ) * n + col / n; return rows[row][d] + columns[col][d] + boxes[idx][d] == 0; } publicvoidplaceNumber(int d, int row, int col){ /* Place a number d in (row, col) cell */ int idx = (row / n ) * n + col / n; rows[row][d]++; columns[col][d]++; boxes[idx][d]++; board[row][col] = (char)(d + '0'); } publicvoidremoveNumber(int d, int row, int col){ /* Remove a number which didn't lead to a solution */ int idx = (row / n ) * n + col / n; rows[row][d]--; columns[col][d]--; boxes[idx][d]--; board[row][col] = '.'; } publicvoidplaceNextNumbers(int row, int col){ if ((col == N - 1) && (row == N - 1)) { sudokuSolved = true; } // if not yet else { // if we're in the end of the row // go to the next row if (col == N - 1) backtrack(row + 1, 0); // go to the next column else backtrack(row, col + 1); } }
publicvoidbacktrack(int row, int col){ /* Backtracking */ // 如果这个位置为空 if (board[row][col] == '.') { //从 0->9进行遍历 for (int d = 1; d < 10; d++) { if (couldPlace(d, row, col)) { placeNumber(d, row, col); placeNextNumbers(row, col); // if sudoku is solved, there is no need to backtrack // since the single unique solution is promised if (!sudokuSolved) removeNumber(d, row, col); } } } else placeNextNumbers(row, col); } }
publicvoidaddSolution(){ List<String> solution = new ArrayList<String>(); for (int i = 0; i < n; ++i) { int col = queens[i]; StringBuilder sb = new StringBuilder(); for(int j = 0; j < col; ++j) sb.append("."); sb.append("Q"); for(int j = 0; j < n - col - 1; ++j) sb.append("."); solution.add(sb.toString()); } output.add(solution); }
publicvoidbacktrack(int row){ for (int col = 0; col < n; col++) { if (isNotUnderAttack(row, col)) { placeQueen(row, col); // 放满了 if (row + 1 == n) addSolution(); // if not proceed to place the rest else backtrack(row + 1); // backtrack removeQueen(row, col); } } } }