LeetCode 37. 解数独
题目类型
- 暴搜
- dfs
题目链接
https://leetcode.cn/problems/sudoku-solver/submissions/
思路
- 对每个没放数的格子,从1-9dfs枚举
- 选择某个数i的时候 判断rows[x][i] cols[y][i] cells[x / 3][y / 3][i]的状态
- 以上判断如果为false,回溯;为true,继续搜索下一个点(x, y + 1)
AC代码
class Solution {
public:
// 行 列 小方格的枚举每个数的状态
bool rows[9][9], cols[9][9], cells[3][3][9];
void solveSudoku(vector<vector<char>>& board) {
memset(rows, false, sizeof rows);
memset(cols, false, sizeof cols);
memset(cells, false, sizeof cells);
// 初始化
for (int i = 0; i < 9; i ++)
{
for (int j = 0; j < 9; j ++)
{
if (board[i][j] != '.')
{
int t = board[i][j] - '1';
rows[i][t] = cols[j][t] = cells[i / 3][j / 3][t] = true;
}
}
}
// 从(0, 0)开始填
dfs(board, 0, 0);
}
bool dfs(vector<vector<char>> &board, int x, int y)
{
if (y == 9) y = 0, x ++;
if (x == 9) return true;
// 如果该位置已经有数了 则换下一个位置
if (board[x][y] != '.') return dfs(board, x, y + 1);
// 否则这个位置可以插入,枚举一下
for (int i = 0; i < 9; i ++)
{
if (!rows[x][i] && !cols[y][i] && !cells[x / 3][y / 3][i])
{
rows[x][i] = cols[y][i] = cells[x / 3][y / 3][i] = true;
board[x][y] = '1' + i;
if (dfs(board, x, y + 1)) return true;
// 回溯
board[x][y] = '.';
rows[x][i] = cols[y][i] = cells[x / 3][y / 3][i] = false;
}
}
return false;
}
};