37. 解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
https://leetcode.cn/problems/sudoku-solver/submissions/618100739/

cpp
class Solution {
public:
bool rows[9][9];
bool cols[9][9];
bool cubes[9][9];
vector<pair<int, int>> blanks; // 存储blanks空白的格子
bool valid = false;
void dfs(vector<vector<char>>& board, int pos) {
if (blanks.size() == pos) {
valid = true;
return;
}
auto [i, j] = blanks[pos];
for (int num = 0; num < 9 && !valid; ++num) {
if (!rows[i][num] && !cols[j][num] && !cubes[((int)(i / 3)) * 3 + (j / 3)][num]) {
rows[i][num] = 1;
cols[j][num] = 1;
cubes[((int)(i / 3)) * 3 + (j / 3)][num] = 1;
board[i][j] = num + '0' + 1;
dfs(board, pos + 1);
// 如果没有成功,那么返回
rows[i][num] = 0;
cols[j][num] = 0;
cubes[((int)(i / 3)) * 3 + (j / 3)][num] = 0;
}
}
return;
}
void solveSudoku(vector<vector<char>>& board) {
memset(rows, false, sizeof(rows));
memset(cols, false, sizeof(cols));
memset(cubes, false, sizeof(cubes));
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int cur_num = board[i][j] - '1';
rows[i][cur_num] = 1;
cols[j][cur_num] = 1;
// cube要算一下是第几个cube
cubes[((int)(i / 3)) * 3 + (j / 3)][cur_num] = 1;
} else {
// i,j空白了
blanks.emplace_back(i, j);
}
}
}
dfs(board,0);
}
};