https://oj.leetcode.com/problems/sudoku-solver/
九宫格数独问题。
一行上为1 2 3 到9
一列上为1 2 3 到9
每个小的3*3格子为 1 2 3 到9
使用深搜递归实现:
在技巧上,使用类的成员变量 vector<vector<char> > board; 这样不用每层递归都传递这个棋盘了
使用类的成员变量 bool flagOK; 标志是否已找到 solution.
从(0,0)位置开始递归,一个个位置加,直到位置到了最后一个。
在每一层上,遍历1 2 3 到 9 ,看看哪个数可以往这里放,然后递归下一层,即下一个位置。
当从下一个位置返回的时候,要把之前设置的值再 恢复 回来
还有个情况会导致返回到上一次,那就是从1 到 9 都遍历完了,仍然都不可以,也要记得恢复回来
class Solution {
public:
vector<vector<char> > board;
bool flagOK;
void solveSudoku(vector<vector<char> > &board) {
if(board.empty())
return;
flagOK = false;
this->board = board;
subSudoku(,);
board = this->board;
} // in rows and cols don't have the same one
bool valide(char num, int p, int q)
{
bool flag = true;
for(int i = ; i < board.size(); i++)
{
if(num == board[i][q])
{
flag = false;
break;
}
}
if(flag)
{
for(int j = ; j < board.size(); j++)
{
if(num == board[p][j])
{
flag = false;
break;
}
}
}
return flag;
} void subSudoku(int i, int j)
{
// till end find solution
if(i == board.size())
{
flagOK = true;
return;
} // num placed
if(board[i][j] != '.')
{
if(j < board.size() - )
{
subSudoku(i,j + );
if(flagOK == true)
return; //不再递归了,已经找到答案了
}
else
{
subSudoku(i+,);
if(flagOK == true)
return;
}
}
else
{
char num;
for(num = ''; num <= ''; num++)
{
// in its small cube
bool OKSmallCube = true;
int smallCubeI = i/;
int smallCubeJ = j/;
// check small cube
for(int s = ; s < ; s++)
{
for(int m = ; m < ; m++)
{
if(board[smallCubeI* + s][smallCubeJ* + m] == num)
{
OKSmallCube = false;
break;
}
}
if(OKSmallCube == false)
break;
} if(OKSmallCube && valide(num,i,j))
{
board[i][j] = num;
if(j < board.size() - )
{
subSudoku(i,j + );
if(flagOK == true)
return;
}
else
{
subSudoku(i+,);
if(flagOK == true)
return;
}
}
board[i][j] = '.'; //注意恢复原样
}
board[i][j] = '.';//注意恢复原样
}
}
};