本题是在leetcode36 题的基础上加深了难度,本题用到了回溯递归的思想,也就是当一个格子中验证1-9这9个数
发现都无效时,会回溯到上一个格子,让它找到一个合适的值,为后面的格子找到合适的值开路。
本题目发现递归的算法,非常难调试,尤其是当数据量大的时候,该代码62行少写了个return然后花费了大量的时间调试
这道题的一个很大的收获就是从细节对递归回溯有进一步的理解
package no1_50;
public class subject037 {
class Solution {
//判断行、列、小九格有没有重复的target
public boolean isValidSudoku(char[][] board, int row, int col, char target) {
int len = board.length;
int t = (int)Math.sqrt(len);
//对行、列进行检查
for(int i=0; i<len; i++) {
if(board[i][col]==target||board[row][i]==target) {
return false;
}
}
int x = t*(row/t);
int y = t*(col/t);
for(int i=x; i<x+t; i++) {
for(int j=y; j<y+t; j++) {
if(board[i][j]==target) {
return false;
}
}
}
return true;
}
public char[][] solveSudoku(char[][] board) {
//遍历数独矩阵,对'.'进行填充,从1到
dfs(board,0,0);
return board;
}
public boolean dfs(char[][] board,int row,int col) {
int len = board.length;
if(col>=len) {
row += 1;
col = 0;
}
//最后一个元素判断完
if(row>=len) return true;
char current = board[row][col];
if(current=='.') {
for(int i=1; i<=len; i++) {
char target = (char)(i+'0');
if(isValidSudoku(board,row,col,target)) {
board[row][col] = target;
if(dfs(board,row,col+1)) {
return true;
} else {
//回溯时是要将填充的数写成'.'
board[row][col] = '.';
}
}
}
//System.out.println(row+"\t"+col);
return false;
}else {
//最开始写的是 dfs(board, row, col+1);
//整整调了一晚上没有调出来
return dfs(board, row, col+1);
}
}
}
public static void main(String[] args) {
subject037 subject = new subject037();
Solution s = subject.new Solution();
char[][] input = {
{'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[][] input = { {'3','4','.','.'},
{'.','.','.','.'},
{'4','3','.','.'},
{'1','2','.','.'},
};
**/
for(int i=0; i<input.length; i++) {
for(int j=0;j<input.length;j++) {
System.out.print(input[i][j]+"\t");
}
System.out.println();
}
System.out.println("=================================================================================");
char[][] result = s.solveSudoku( input );
System.out.println("=================================================================================");
for(int i=0; i<input.length; i++) {
for(int j=0;j<input.length;j++) {
System.out.print(result[i][j]+"\t");
}
System.out.println();
}
}
}