什么是数独
数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复 [1] 。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

示例 1: 输入:
[
[“5”,“3”,".",".",“7”,".",".",".","."],
[“6”,".",".",“1”,“9”,“5”,".",".","."],
[".",“9”,“8”,".",".",".",".",“6”,"."],
[“8”,".",".",".",“6”,".",".",".",“3”],
[“4”,".",".",“8”,".",“3”,".",".",“1”],
[“7”,".",".",".",“2”,".",".",".",“6”],
[".",“6”,".",".",".",".",“2”,“8”,"."],
[".",".",".",“4”,“1”,“9”,".",".",“5”],
[".",".",".",".",“8”,".",".",“7”,“9”]
]
输出: true
分析:遍历输入,检测每一行、列、子九宫格内出现的1~9的数字有没有重复即可。
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
bool row [9][9]={false}; //row的index和num
bool col [9][9]={false}; //col的index和num
bool block [9][9]={false}; //block的index和num
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '1';//数独中的1~9 在数组中作为0~8
int blockindex = (i/ 3) * 3 + j / 3;
if (row[i][num] || col[j][num] || block[blockindex][num])
return false;
row[i][num] = true;
col[j][num] = true;
block[blockindex][num] = true;
}
}
}
return true;
}
};
解数独
编写一个程序,通过已填充的空格来解决数独问题。一个数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次, 数字 1-9 在每一列只能出现一次, 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
分析: 回溯递归 dfs
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
bool row[9][9] = { false }; //row的index和num
bool col[9][9] = { false }; //col的index和num
bool block[9][9] = { false }; //block的index和num
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '1';//数独中的1~9 在数组中作为0~8
int blockindex = (i / 3) * 3 + j / 3;
row[i][num] = true;
col[j][num] = true;
block[blockindex][num] = true;
}
}
}
dfs(board, row, col, block, 0, 0);
printboard(board);
}
bool dfs(vector<vector<char>>& board, bool row[9][9], bool col[9][9], bool block[9][9], int rowindex, int colindex) {
//从第一行开始向右寻找第一个为空的宫格。
while (board[rowindex][colindex] != '.'&&rowindex<9&&colindex<9) {
if (++colindex >= 9) {
rowindex++;
colindex = 0;
}
if (rowindex >= 9) {
return true;
}
}
for (int num = 0; num < 9; num++) {
int blockIndex = rowindex / 3 * 3 + colindex/ 3;
if (!row[rowindex][num] && !col[colindex][num] && !block[blockIndex][num]) {
// 递归
board[rowindex][colindex] = (char)('1' + num);
row[rowindex][num] = true;
col[colindex][num] = true;
block[blockIndex][num] = true;
if (dfs(board, row, col, block, rowindex, colindex)) {
return true;
}
else {
// 回溯
row[rowindex][num] = false;
col[colindex][num] = false;
block[blockIndex][num] = false;
board[rowindex][colindex] = '.';
}
}
}
return false;
}
void printboard(vector<vector<char>> board)
{
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cout << board[i][j] << " ";
}
cout << endl;
}
}
};