leetcode#37. Sudoku Solver
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3×3 宫内只能出现一次。
空白格用 ‘.’ 表示。
![]()
一个数独。![]()
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9×9 形式的。
//获得一个解即可。那么很简单了,得到当前空格能填的数字,然后dfs即可。辅助函数我只能靠回忆了。一个是获得位空的空格的坐标,一个是该空格可放入的数字集合。 class Solution{ public: using boolVec = vector<vector<bool>>; void solveSudoku(vector<vector<char>>& board) { int m = board.size(), n = board[0].size(); vector<vector<bool> > rowFlag(m, vector<bool>(n, false));//ffffffff以8个bit代表每个数字在m行有没有出现,默认是没有 vector<vector<bool> > colFlag(m, vector<bool>(n, false));//ffffffff vector<vector<bool> > cellFlag(m, vector<bool>(n, false));// for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] >= '1' && board[i][j] <= '9') { int c = board[i][j] - '1';//为什么要减一呢?因为我们用索引0-8保存数字1-9标识 rowFlag[i][c] = true; colFlag[j][c] = true; cellFlag[3 * (i / 3) + j / 3][c] = true; } } } solveSudoku(board, { 0,0 }, rowFlag, colFlag, cellFlag); int i = 3; } bool solveSudoku(vector<vector<char>>& board, pair<int, int> pos, boolVec& rowFlag, boolVec& colFlag, boolVec& cellFlag) { if (pos.first == -1) return true; auto blank = getNextblank(board, pos, '.'); if (blank.first == -1) return true; auto to_insert = getValidChar(board, blank, rowFlag, colFlag, cellFlag); if (to_insert.empty()) return false; for (int i = 0; i != to_insert.size(); ++i) { if (to_insert[i] == false) continue; board[blank.first][blank.second] =i+1+'0' ; rowFlag[blank.first][i] = true; colFlag[blank.second][i] = true; cellFlag[3 * (blank.first / 3) + blank.second / 3][i] = true; if (solveSudoku(board, blank, rowFlag, colFlag, cellFlag)) { cout << "succefss" << endl; return true; } board[blank.first][blank.second] = '.'; rowFlag[blank.first][i] = false; colFlag[blank.second][i] = false; cellFlag[3 * (blank.first / 3) + blank.second / 3][i] = false; } return false; } pair<int, int> getNextblank(vector<vector<char>>& board, pair<int, int> pos, char c) { for (int i = pos.first; i != board.size(); ++i) for (int j = 0; j != board[0].size(); ++j) if (board[i][j] == c) return { i,j }; return { -1,-1 }; } //返回可插入的字符列表 //using boolVec = vector<vector<bool>>; vector<bool> getValidChar(vector<vector<char>>& board, pair<int, int> pos, boolVec& rowFlag, boolVec& colFlag, boolVec& cellFlag) { int m = board.size(), n = board[0].size(); int row = pos.first; int col = pos.second; auto chars1 = rowFlag[row]; auto chars2 = colFlag[col]; auto chars3 = cellFlag[3 * (row / 3) + col / 3]; vector<bool> result(chars1.size(), false); for (int i = 0; i != chars1.size(); ++i) { if (!chars1[i] && !chars2[i] && !chars3[i]) result[i] = true; else result[i] = false; } return result; } };

浙公网安备 33010602011771号