编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
方法一:递归
思路:
【1】先初始化将行,列,九宫格的数存入set中。
【2】遍历数组,找到一个'.'的字符,for循环遍历1-9。找到未出现在行、列、九宫格中的数
【3】重复1,2步骤直到数组被填充完
//row,column为开始遍历的位置
int dpSolve(vector<vector<char>>& board, set<char> rowSet[],
set<char> columnSet[], set<char> boxSet[], int row, int column) {
int flag = 0;
//遍历填充
while (row < board.size()) {
while (column < board.size()) {
char ch = board[row][column];
if (ch == '.') {
flag = 1;
break;
}
++column;
}
if (flag == 1) {
break;
}
++row;
column = 0;
}
//全部填充完
if (flag == 0) {
return 1;
}
int boxIndex = row / 3 * 3 + column / 3;
for (int i = 1;i <= 9;i++) {
char ch = i + '0'; //填充的字符
if (rowSet[row].find(ch) == rowSet[row].end() &&
columnSet[column].find(ch) == columnSet[column].end() &&
boxSet[boxIndex].find(ch) == boxSet[boxIndex].end()) {
board[row][column] = ch;
rowSet[row].insert(ch);
columnSet[column].insert(ch);
boxSet[boxIndex].insert(ch);
int ans = dpSolve(board, rowSet, columnSet, boxSet, row, column);
if (ans == 1) {
return 1;
}
else { //不符合条件进行回溯
board[row][column] = '.';
rowSet[row].erase(ch);
columnSet[column].erase(ch);
boxSet[boxIndex].erase(ch);
}
}
}
return 0;
}
void solveSudoku(vector<vector<char>>& board) {
set<char> rowSet[9], columnSet[9], boxSet[9];
//初始化
for (int row = 0;row < board.size();++row) {
for (int column = 0;column < board[row].size();++column) {
char ch = board[row][column];
int boxIndex = row / 3 * 3 + column / 3;
if (ch != '.') {
rowSet[row].insert(ch);
columnSet[column].insert(ch);
boxSet[boxIndex].insert(ch);
}
}
}
dpSolve(board, rowSet, columnSet, boxSet, 0, 0);
}