LeetCode第37题--解数独
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
class Solution {
private:
bool dfs(vector<vector<char>> &board, vector<vector<bool>> &vecRow,
vector<vector<bool>> &vecCol, vector<vector<bool>> &vecSqu, int i, int j)
{
while(board[i][j] != '.') //找到第一个不为'.'的位置
{
if(++j >= board[0].size())
{
j=0;
i++;
}
if(i >= board.size())
{
return true;
}
}
for(int num = 0; num < 9; num++) //从数字索引0-8中找出一个数字填入,对应字符'1'-'9'
{
int squIndex = i/3+j/3*3;
if(!vecRow[i][num] && !vecCol[j][num] && !vecSqu[squIndex][num])
{
vecRow[i][num] = true;
vecCol[j][num] = true;
vecSqu[squIndex][num] = true;
board[i][j] = num+1+'0';
if(dfs(board, vecRow, vecCol, vecSqu, i, j)) //注意此处递归仍然是从i,j开始
{
return true;
}
else //不符合条件,进行回溯处理
{
vecRow[i][num] = false;
vecCol[j][num] = false;
vecSqu[squIndex][num] = false;
board[i][j] = '.';
}
}
}
return false;
}
public:
void solveSudoku(vector<vector<char>>& board) {
int row = board.size();
int col = board[0].size();
vector<vector<bool>> vecRow(row, vector<bool>(col, false));
vector<vector<bool>> vecCol(row, vector<bool>(col, false));
vector<vector<bool>> vecSqu(row, vector<bool>(col, false));
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
if(board[i][j] != '.')
{
int numIndex = board[i][j]-'0'-1;
vecRow[i][numIndex] = true;
vecCol[j][numIndex] = true;
vecSqu[i/3+j/3*3][numIndex] = true;
}
}
}
dfs(board, vecRow, vecCol, vecSqu, 0, 0);
}
};
采用递归回溯的方法,设置3个vector,分别代表行,列,以及小正方形填入的数字是否合法,深度优先遍历,获取到一个正确答案即可。