思路 回溯算法
每个节点有两个属性:
- 路径
- 选择列表
路径是board,选择列表用check函数排除掉不合题意的选项。backTrack函数用来遍历节点,参数是节点的属性。
套用回溯算法模板即可。注意要只求一种情况,多种情况会运行超时。
class Solution {
public:
bool check(vector<vector<char>> board, int row, int col, char num) {
//判断同一行
if (count(board[row].begin(), board[row].end(), num)) return true;
//判断同一列
for (int i = 0; i < 9; i ++) {
if (board[i][col] == num) return true;
}
//判断3*3方格
int erow = row + 1, ecol = col + 1;
while (erow % 3 != 0) erow ++;
while (ecol % 3 != 0) ecol ++;
int brow = erow - 3, bcol = ecol - 3;
for (int i = brow; i <= erow - 1; i ++) {
for (int j = bcol; j <= ecol - 1; j ++) {
if (board[i][j] == num) return true;
}
}
return false;
}
bool backTrack(vector<vector<char>>& board, int row, int col) {
if (row == 9) return true; //此时遍历完整个路径
if (board[row][col] != '.') { //board[row][col]不可放数
if (col == 8) return backTrack(board, row + 1, 0);
else return backTrack(board, row, col + 1);
}
for (int i = 1; i <= 9; i ++) {
if (check(board, row, col, i + '0')) continue;
board[row][col] = i + '0';
bool flag = false;
if (col == 8) flag = backTrack(board, row + 1, 0);
else flag = backTrack(board, row, col + 1);
if (flag) return true; //结束递归
board[row][col] = '.';
}
return false;
}
void solveSudoku(vector<vector<char>>& board) {
backTrack(board, 0, 0);
}
};