tema:
Resolviendo Sudoku
fuente:
Ideas para resolver problemas: retroceder
Primero averigüe todas las posiciones vacías, seleccione cada posición vacía a su vez y seleccione el número de candidato establecido de acuerdo con la fila, columna y celda actual. Recurse + retroceso para cada número del conjunto.
- Condición de terminación recursiva: se llenan todas las posiciones vacías
La función aquí tiene un valor de retorno bool, que es conveniente para el retorno directo. Antes de encontrar la solución, repita cada número + retroceso. Una vez que se encuentra la solución, regresará inmediatamente y no se puede hacer retroceso. Si regresa, la posición ocupada se borrará.
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
vector<int> space;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] == '.') {
space.push_back(i * 10 + j);
}
}
}
back(board, space, 0);
}
bool back(vector<vector<char>>& board, const vector<int>& space, int start) {
if (start == space.size()) {
return true;
}
int t = space[start];
int x = t / 10; // x行
int y = t % 10; // y列
for (int i = 0; i < 9; i++) {
char v = i+1+'0';
if (check(board, x, y, v)) {
board[x][y] = v;
if (back(board, space, start+1)) return true;
board[x][y] = '.'; // 找到以后不能再回溯,所以函数直接返回不能到达这里
}
}
return false;
}
bool check(const vector<vector<char>>& board, int x, int y, char v) {
// 第x行
for (int i = 0; i < 9; i++) {
if (board[x][i] == v) return false;
}
// 第y列
for (int i = 0; i < 9; i++) {
if (board[i][y] == v) return false;
}
// 当前单元格
int row = x / 3 * 3;
int col = y / 3 * 3;
for (int r = row; r < row+3; r++) {
for (int c = col; c < col+3; c++) {
if (board[r][c] == v) return false;
}
}
return true;
}
};