编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 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;
}
}
本文详细介绍了如何使用Python编写一个数独求解程序,通过回溯大法实现,包括dfs函数的递归过程和isValid方法的逻辑验证。通过实例展示了如何填充空格,确保每行、每列和每个3x3宫格内数字唯一。
555

被折叠的 条评论
为什么被折叠?



