LeetCode 37:解数独
基本思路
主要思路是深度优先搜索,依次填充每个空位。重点在于降低每次DFS的开销。我们尝试对空位填充数字时,要在尽可能短的时间内找到可以填充的数字。所以可以用一些辅助数组分别保存当前位置所在的行、列、九宫格中已有的数字,这样就不用实时检查所在行、列、九宫格中的其它数字。
代码
class Solution {
public:
bool dfs(vector<vector<char>>& board, std::vector<std::vector<bool>>& rowVec,
std::vector<std::vector<bool>>& colVec, std::vector<std::vector<bool>>& blockVec,
std::vector<std::pair<int, int>> emptyPos, int thisEmpty)
{
if(emptyPos.size() == thisEmpty) return true;
int row = emptyPos[thisEmpty].first;
int col = emptyPos[thisEmpty].second;
int blockID = (row/3)*3 + col/3;
std::vector<int> numVec;
for(int num = 1; num <= 9; num++)
{
if(!rowVec[row][num] && !colVec[col][num] && !blockVec[blockID][num])
{
numVec.push_back(num);
}
}
bool result = false;
for(int i=0; i<numVec.size(); i++)
{
int num = numVec[i];
board[row][col] = num+'0';
rowVec[row][num] = true;
colVec[col][num] = true;
blockVec[blockID][num] = true;
result = result || dfs(board, rowVec, colVec, blockVec, emptyPos, thisEmpty+1);
if(result == true)
{
break;
}
else
{
board[row][col] = '.';
rowVec[row][num] = false;
colVec[col][num] = false;
blockVec[blockID][num] = false;
}
}
return result;
}
void solveSudoku(vector<vector<char>>& board) {
std::vector<std::vector<bool>> rowVec(9, std::vector<bool>(10, false));
std::vector<std::vector<bool>> colVec(9, std::vector<bool>(10, false));
std::vector<std::vector<bool>> blockVec(9, std::vector<bool>(10, false));
std::vector<std::pair<int, int>> emptyPos;
//初始化存储矩阵
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
if(board[i][j] != '.')
{
int tmp = board[i][j]-'0';
rowVec[i][tmp] = true;
colVec[j][tmp] = true;
int blockID = (i/3)*3 + j/3;
blockVec[blockID][tmp] = true;
}
else
{
emptyPos.push_back({i,j});
}
}
}
dfs(board, rowVec, colVec, blockVec, emptyPos, 0);
}
};