写代码没有思路,先将辅助的变量定义好和初始化有助于厘清思路
难点在于一个空格所有数字都尝试失败之后如何回到上一个状态,可以使用List存储需要填写的空格方便回溯使用
还有一个要注意的点是每一格空格填数字的循环中要加上!valid条件,否则得到正确答案后回到上一个空格的遍历循环时还是会继续执行
//每个空格执行进行所有数字的尝试
for (int i = 0; i < 9 && !valid; i++){
}
完整代码(带测试用例):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
//是否已经填充
private boolean[][] rows = new boolean[9][9];
private boolean[][] columns = new boolean[9][9];
private boolean[][][] boxes = new boolean[3][3][9];
private List<int[]> space = new ArrayList<>();
boolean valid = false;
//初始化
public void solveSudoku(char[][] board) {
int len = board.length;
int wid = board[0].length;
for (int i = 0; i < len; i++) {
for (int j = 0; j < wid; j++) {
int num = board[i][j] - '0' - 1;
if('.' == board[i][j]){
space.add(new int[]{
i, j});
}else{
rows[i][num] = true;
columns[j][num] = true;
boxes[i / 3][j / 3][num] = true;
}
}
}
dfs(board,0);
}
public void dfs(char[][] board,int start){
if(start == space.size()){
valid = true;
return;
}
int[] pos = space.get(start);
int x = pos[0];
int y = pos[1];
//这个!valid很重要,当已经完成了正确答案返回到这里的时候就终止循环不要再瞎改了
// 否则还是会继续把当前的位置改为其他数字
for (int i = 0; i < 9 && !valid; i++) {
//尝试填入数字
if(!rows[x][i] && !columns[y][i] && !boxes[x / 3][y / 3][i]){
rows[x][i] = true;
columns[y][i] = true;
boxes[x / 3][y / 3][i] = true;
board[x][y] = (char) ('0' + i + 1);
dfs(board,start + 1);
rows[x][i] = false;
columns[y][i] = false;
boxes[x / 3][y / 3][i] = false;
}
}
}
public void print(){
for (boolean[] row : rows) {
System.out.println(Arrays.toString(row));
}
System.out.println("-----------");
for (boolean[] column : columns) {
System.out.println(Arrays.toString(column));
}
System.out.println("------------");
for (boolean[][] box : boxes) {
for (boolean[] booleans : box) {
System.out.println(Arrays.toString(booleans));
}
}
System.out.println("--------------");
// System.out.println(space);
}
public static void main(String[] args) {
char[][] 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'}
};
Solution solution = new Solution();
solution.solveSudoku(board);
// solution.print();
for (char[] chars : board) {
System.out.println(Arrays.toString(chars));
}
}
}