leetcode37 解数独
还是常规的回溯,这题理论上可以通过不少方式剪枝,这里都没有考虑。
需要注意的是,Java数组clone,一维数组是深拷贝,多维数组是浅拷贝,这里二维数组用clone实际上会得到同一个对象。
代码:
class Solution {
char[][] res = new char[9][9];
private boolean check(char[][] board,int r,int c){
int rs = (r/3)*3;
int cs = (c/3)*3;
for(int j = 0;j < 9;j++){
if(j == c) continue;
if(board[r][c] == board[r][j]) return false;
}
for(int i = 0;i < 9;i++){
if(i == r) continue;
if(board[r][c] == board[i][c]) return false;
}
for(int i = rs;i < rs+3;i++){
for(int j = cs;j < cs+3;j++){
if(r == i && c == j) continue;
if(board[r][c] == board[i][j]) return false;
}
}
return true;
}
private void trackBack(char[][] board,int r,int c){
if(r >= 9){
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++)
res[i][j] = board[i][j];
}
}else{
if(board[r][c] != '.'){
int cnext = c+1 >= 9 ? 0 : c+1;
int rnext = c+1 >= 9 ? r+1 : r;
trackBack(board, rnext, cnext);
}else{
for(int i = 1;i <= 9;i++){
board[r][c] = (char) (i + 48);
if(check(board, r, c)){
int cnext = c+1 >= 9 ? 0 : c+1;
int rnext = c+1 >= 9 ? r+1 : r;
trackBack(board, rnext, cnext);
}
board[r][c] = '.';
}
}
}
}
public void solveSudoku(char[][] board) {
trackBack(board, 0, 0);
for(int i = 0;i < 9;i++){
for(int j = 0;j < 9;j++)
board[i][j] = res[i][j];
}
}
}
17ms 35.6MB