题目:Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
思路:
首先是更新函数,对应编写每一行每一列以及每一个子3*3的小格子的检验函数,在主函数里面更新他们,这里要注意的就是“ board[i][j]-'0' ”,而不能写成“ + ”。
设置的三个数组,rowValid ,colValid ,subBoard,分别代表第i行第j个数字是否满足要求,第i列第j个数是否满足要求,第i个小格子第j个数是否满足要求。
判断的时候如果为0则满足要求,否则返回为false。
至于清空之前状态则置1即可。
真正判断的时候,是以第几个小格子来判断的,大小为0<=index<=80,大于80,返回。
对应于某一个index,可以求解出对应的行列值,如果原来存在数字,之前递归下一个index。
否则从1到9,一个一个的替换,先是判断这个数字是否合格,然后赋值,再是更新,继续递归下一个index,最后回溯回来;
先是clear,清空返回原来状态,当然还需要将原来的状态置为“ . ”;
代码:
class Solution {
public:
int rowValid[9][10];//判断第i行数字j是否合格
int colValid[9][10];//判断第i列数字j是否合格
int subBoard[9][10];//判断第i个小个子(3*3)数字j是否合格
bool isValid(int row,int col,int val){
if(rowValid[row][val]==0 && colValid[col][val]==0 && subBoard[row/3*3+col/3][val]==0 ) return true;
return false;
}
void fill(int row,int col,int val){//更新状态
rowValid[row][val]=1;
colValid[col][val]=1;
subBoard[row/3*3+col/3][val]=1;
}
void clear(int row,int col,int val){//清除原来状态
rowValid[row][val]=0;
colValid[col][val]=0;
subBoard[row/3*3+col/3][val]=0;
}
bool solver(vector<vector<char> > &board,int index){//index表示第几个小个子
// 0<=index<<80
if(index>80) return true;//标准的回溯判断
int row,col;
row=index/9;col=index-9*row;
if(board[row][col]!='.'){
return solver(board,index+1);
}
for(int i=1;i<=9;i++){
if(isValid( row, col, i) ){
board[row][col]=i+'0';
fill( row, col,i );
if(solver( board, index+1)) return true;
clear( row, col,i );
}
}
board[row][col]='.';
return false;
}
void solveSudoku(vector<vector<char> > &board) {
//首先更新3个数组
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]!='.')
fill( i,j,board[i][j]-'0' );
}
}
solver(board,0);
}
};