编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
解题思路:
首先定义三个数据结构,rows、cols为二维数组,grid为三维数组,二维数组rows,cols表示的是第i行有没有j这个数,grid表示的是第几行第几列的九宫格有没有某个数,初始化都是false,一个vector<pair<int,int>>用来存储空格的位置,然后把初始数独输入到行列九宫格中,dfs代码思路也很清晰,找到某个空的位置,循环1——9,判断该位置行列九宫格有没有某个数,没有就直接放到该空格上,然后更新那三个数组,并且接着往后搜索,代码如下:
class Solution {
private:
bool rows[9][9];//rows[i][j] 表示第 i 行是否存在 j + 1
bool cols[9][9];//cols[i][j] 表示第 i 列是否存在 j + 1
bool grid[3][3][9];//grid[i][j][k] 表示第 {i, j} 个九宫格是否存在 k
vector<vector<char>> ans;
vector<pair<int,int>> spaces;//记录下空白格的坐标
public:
void dfs(vector<vector<char>>& board, int index){
if(index == spaces.size()){
ans = board;
return;
}
//找到一个空白的位置
pair<int,int> site = spaces[index];
//确定行列
int row = site.first;
int col = site.second;
for(int i = 0; i < 9; i ++){
if(!rows[row][i] && !cols[col][i] && !grid[row / 3][col / 3][i]){
board[row][col] = i + '1';
rows[row][i] = true;
cols[col][i] = true;
grid[row / 3][col / 3][i] = true;
dfs(board, index + 1);
//回溯
rows[row][i] = false;
cols[col][i] = false;
grid[row / 3][col / 3][i] = false;
}
}
}
void solveSudoku(vector<vector<char>>& board) {
//初始化
memset(rows, false, sizeof(rows));
memset(cols, false, sizeof(cols));
memset(grid, false, sizeof(grid));
//把初始数独输入到行列九宫格中
for(int i = 0; i < 9; i ++){
for(int j = 0; j < 9; j ++){
if(board[i][j] == '.'){
spaces.push_back({
i,j});
}else{
rows[i][board[i][j] - '1'] = true;
cols[j][board[i][j] - '1'] = true;
grid[i / 3][j / 3][board[i][j] - '1'] = true;
}
}
}
dfs(board, 0);
board = ans;
}
};