编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
Note:
递归+回溯,按列遍历,一行的所有列遍历完后遍历下一行:
class Solution {
public:
vector<char> numbers = {
'1', '2', '3', '4', '5', '6', '7', '8', '9'};
void solveSudoku(vector<vector<char>>& board) {
helper(board, 0, 0);
}
bool helper(vector<vector<char>>& board, int row, int col){
if(col==9){
return helper(board, row+1, 0);
}
if(row==9){
return true;
}
if(board[row][col]!='.'){
return helper(board, row, col+1);
}
for(char c : numbers){
if(check(board, row, col, c)){
board[row][col] = c;
if(helper(board, row, col+1)){
return true;
}
board[row][col] = '.';
}
}
return false;
}
bool check(vector<vector<char>>& board, int row, int col, char c){
for(int i=0;i<9;i++){
// 判断行列是否有相对元素
if(board[row][i] == c || board[i][col] == c)
return false;
// 判断格子内是否有相同元素
if(board[row/3*3+i/3][col/3*3+i%3] == c)
return false;
}
return true;
}
};
上面的代码主要耗时在check()
函数上,因此可以使用额外的变量记录是否有重复数字:
class Solution {
public:
vector<char> numbers = {
'1', '2', '3', '4', '5', '6', '7', '8', '9'};
vector<vector<int>> row_used = vector<vector<int>>(9, vector<int>(9, 0));
vector<vector<int>> col_used = vector<vector<int>>(9, vector<int>(9, 0));
vector<vector<vector<int>>> cell_used = vector<vector<vector<int>>>(3, vector<vector<int>>(3, vector<int>(9, 0)));
void solveSudoku(vector<vector<char>>& board) {
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.')
continue;
int temp = board[i][j]-'1';
row_used[i][temp] = 1;
col_used[j][temp] = 1;
cell_used[i/3][j/3][temp] = 1;
}
}
helper(board, 0, 0);
}
bool helper(vector<vector<char>>& board, int row, int col){
if(col==9){
return helper(board, row+1, 0);
}
if(row==9){
return true;
}
if(board[row][col]!='.'){
return helper(board, row, col+1);
}
for(char c : numbers){
int temp = c - '1';
if(row_used[row][temp] || col_used[col][temp] || cell_used[row/3][col/3][temp]){
continue;
}
else{
board[row][col] = c;
row_used[row][temp] = col_used[col][temp] = cell_used[row/3][col/3][temp] = 1;
if(helper(board, row, col+1)){
return true;
}
board[row][col] = '.';
row_used[row][temp] = col_used[col][temp] = cell_used[row/3][col/3][temp] = 0;
}
}
return false;
}
};