非递归回溯解数独,用java实现
时间: 2024-10-12 17:17:00 浏览: 38
Java实现解数独的小程序共4页.pdf.zip
非递归回溯法是一种解决数独问题的有效策略,它避免了函数深度嵌套带来的效率低下的问题。在Java中,我们可以采用数组来表示数独的格子,并通过两层循环遍历每一行和每一列,检查当前位置是否可以填入合法数字。
以下是简单的Java代码实现:
```java
import java.util.Arrays;
public class SudokuSolver {
private static final int SIZE = 9;
private boolean[][] board; // 数独网格
public SudokuSolver(boolean[][] board) {
this.board = board;
}
// 检查当前位置(行i, 列j)是否可以填入数字n
private boolean isValid(int i, int j, int n) {
// 检查行、列以及3x3宫格都不冲突
for (int k = 0; k < SIZE; k++) {
if (board[i][k] == n || board[k][j] == n || board[i / 3 * 3 + k / 3 / 3][j / 3 * 3 + k % 3 / 3] == n)
return false;
}
return true;
}
// 回溯填数过程
private void solve(int i, int j) {
if (j == SIZE) { // 到达右边界,换行继续填下一个单元格
i++;
j = 0;
}
if (i >= SIZE) { // 解决完一行,返回上一层处理下一行
return;
}
// 尝试填入1到9的每个数字
for (int n = 1; n <= SIZE; n++) {
if (isValid(i, j, n)) { // 如果合法,尝试填入并进入下一格
board[i][j] = n;
solve(i, j + 1); // 递进处理下一个单元格
if (solve(i, j)) // 如果无法继续则回退到上一步
break;
}
}
}
// 主入口,开始求解
public boolean solveSudoku() {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE && board[i][j] == 0; j++) {
solve(i, j);
if (!board[i][j]) // 如果还没找到解,说明之前的填入有误,需要回溯
return false;
}
}
return true;
}
// 示例
public static void main(String[] args) {
boolean[][] sudokuBoard = {
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}
};
SudokuSolver solver = new SudokuSolver(sudokuBoard);
System.out.println(Arrays.deepToString(solver.solveSudoku() ? solver.board : "No solution found"));
}
}
```
这个程序首先初始化一个数独矩阵,然后在主函数`main`中创建一个`SudokuSolver`实例,并尝试解决数独。如果找到解决方案,它会打印出填充后的数独;若无解,则显示"No solution found"。
阅读全文