您的位置:首页 > 其它

LeetCode 37. Sudoku Solver|DFS算法

2016-09-21 00:12 316 查看

题目简介

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…



题目分析

这道题目虽然是hard,但是算法角度来看这道题一点都不难。首先我是先做了一个easy的相关题目练手,顺带把有关这题的函数写了。也就是判断一个数独是否有效(含有空格的形况下),也就是对每行,每个九宫格,每列,进行检查有没有重复使用的数字,时间复杂度为O(N^2),看起来这个复杂度很可怕,但其实因为N非常小,几乎可以看成是常数级地运算。

算法分析

这道题一看就是用DFS的穷搜的方法,每个待定数字一个一个搜索,出现死路则回溯,时间复杂度看起来也是十分可怕O(N^N),但是实际上,由于N很小,以及在DFS期间剪掉了很多枝,所以在运行时间上来看,还是十分有效的。已经,这里在check上面可以有个小改进,实际上对新加入来的数字,只需要检验其所在的行、列和九宫格是否有效就可以了,不必对整个数独进行检验,在检验上的时间复杂度可以减少一个数量级,但是由于N很小,我就没有改了。

void print(vector<vector<char> > board){
for(int i = 0 ; i < 9 ; i++){
for(int j = 0 ; j < 9 ; j++)
cout<<board[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}

void initial_used(bool * used){
for(int i = 0 ; i < 9 ; i ++)
used[i] =false;
}
bool isValidSudoku(vector<vector<char> >& board) {
bool *used = new bool [9];
// check row
for (int i =0 ;  i < 9 ;i++){
initial_used(used);
for(int j = 0 ; j < 9 ; j++){
if(board[i][j]!='.')
{
//cout<<board[i][j]-'0'<<endl;
if(used[board[i][j]-'1']) return false;
used[board[i][j]-'1'] =true;
}
}
}
//check col
for (int j =0 ;  j < 9 ;j++){
initial_used(used);
for(int i = 0 ; i < 9 ; i++){
if(board[i][j]!='.')
{
if(used[board[i][j]-'1']) return false;
used[board[i][j]-'1'] =true;
} }
}
// check grid
int beg[9][2] = {{0,0},{0,3},{0,6},{3,0},{3,3},{3,6},{6,0},{6,3},{6,6}};

for(int k = 0 ;  k < 9 ; k++ ){
int x = beg[k][0];
int y = beg[k][1];
initial_used(used);
for(int i = 0 ;i<3;i++){
for(int j = 0 ;j<3 ;j++){
if(board[x+i][y+j]!='.')
{
if(used[board[x+i][y+j]-'1']) return false;
used[board[x+i][y+j]-'1'] =true;
}
}
}
}

delete[] used;
return true;

}

void solve(vector<vector<char> >& board , int x , int y ,bool &yes){

if(y==9){
y= 0 ;x++;
}
if(x==9){
yes = true;
return ;
}

while(board[x][y]!='.'){
y++;

if(y==9){
y= 0 ;x++;
}
if(x==9){
yes = true;
return ;
}
}
//cout<<count++<<endl;
//print(board);
for(int letter = 0 ; letter< 9 ; letter ++){
board[x][y]=letter+'1';
if(isValidSudoku(board)){
solve(board,x,y+1,yes);
if(yes) return ;
}

}
board[x][y] = '.';
}

void solveSudoku(vector<vector<char> > & board) {

bool yes = false;
int x , y;
for(int i = 0 ; i< 9 ;i++)
for(int j = 0 ; j < 9;j++)
if(board[i][j]=='.'){
x = i;
y= j;
goto solve_pro;
}
solve_pro:

solve(board,x,y,yes);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode dfs 算法