编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 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"]]
使用回溯大法: public class Demo1 { public static void main(String[] args) { char[][] chars = {{'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'}}; //char[][] chars ={{'1','.','3'}, {'.','3','.'}, {'3','.','.'}}; new Solution().solveSudoku(chars); } } class Solution { public void solveSudoku(char[][] board) { dfs(board, 0, 0); } private boolean dfs(char[][] board, int i, int j) { if (i == board.length || j == board[i].length ) { return true; } char cur = board[i][j]; if (cur == '.') { boolean flag = false; for (int k = 1; k <= 9; k++) { //合法 if (isValid(i, j, k, board)) { board[i][j] = (char) (k + 48); //print(board); if (j < board[i].length - 1) { flag = dfs(board, i, j+1); } else { flag =dfs(board, i + 1, 0); } if (flag) { return true; } else { //回溯 board[i][j] = '.'; } } } } else { if (j < board[i].length - 1) { return dfs(board, i, j+1); } else { return dfs(board, i + 1, 0); } } return false; } /** * 判断位置是否合法 * @param i * @param j * @param k * @param arr * @return */ private boolean isValid(int i, int j, int k, char[][] arr) { //行比较 char[] rowArr = arr[i]; for (int x = 0; x < arr[0].length; x++) { if (x != j && rowArr[x] == (char) (k + 48)) { return false; } } //列比较 for (int y = 0; y < arr.length; y++) { if (y != i && arr[y][j] == (char) (k + 48)) { return false; } } //九宫比较 int s1 = (i / 3) * 3; int s2 = (j / 3) * 3; for (int p = s1; p < s1 + 3; p++) { for (int q = s2; q < s2 + 3; q++) { if (arr[p][q] == (char) (k + 48)) { return false; } } } return true; } }