思路: 思路其实很容易想到,就是简单粗暴的试每一种可能性。每一个格子都有9种可能性。所以这边我们采用backtracking的方式。遍历矩阵,每碰到一个空格,就插入1-9(这也是一个loop),每插入一次,先要检测插入之后的矩阵是不是一个valid矩阵。如果是valid,然后就要检测当前的矩阵能否被成功解决(recursion)。因为很有可能你插入一个数,导致当前的矩阵是无解的。如果导致了矩阵无解,那么我们就要开始backtracking,将当前元素重新置为空格。直到左右的格子都被填上数字,此时代表已找出正解。我明显对于recusion和backtraking这类题目的判断很模糊。我不能准确地找出base case,也不能明确的判断出什么时候recursion结束,什么时候backtracking开始。也许我可以安慰自己说,至少你写的代码已经很接近正确答案了,你的思路和标答思路一模一样。但是这些都是假象,真像就是我基本功不扎实。这题我确实暂时超出我能力范围外,我没什么好说的,只想说如果害怕一类题目就一直逃避的话,那永远也战胜不了他。下面展示代码:
class Solution {
public void solveSudoku(char[][] board) {
canSolve(board);
}
public boolean canSolve(char[][] board) {
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
char number = board[i][j];
if(number == '.'){
for(int n = 1; n < 10; n++){
char ch = (char)(n + '0'); // int to char
if(isValidSudoku(board,i,j,ch)){
board[i][j] = ch;
if(canSolve(board)) return true;
else board[i][j] = '.';
}
}
return false;
}
}
}
return true;// 全部都是数字,代表全部填写完毕,已经找出正确答案
}
public boolean isValidSudoku(char[][] board, int row, int col, char ch) {
for(int i = 0; i < 9; i++) {
if(board[i][col] != '.' && board[i][col] == ch) return false;
if(board[row][i] != '.' && board[row][i] == ch) return false;
if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' && board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == ch) return false;
}
return true;
}
}
总结: 无