# 解数独

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

 

示例:

输入:board = 
    [["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"]]

输出:
[["5","3","4","6","7","8","9","1","2"], ["6","7","2","1","9","5","3","4","8"], ["1","9","8","3","4","2","5","6","7"], ["8","5","9","7","6","1","4","2","3"], ["4","2","6","8","5","3","7","9","1"], ["7","1","3","9","2","4","8","5","6"], ["9","6","1","5","3","7","2","8","4"], ["2","8","7","4","1","9","6","3","5"], ["3","4","5","2","8","6","1","7","9"]]
解释:
输入的数独如上图所示,唯一有效的解决方案如下所示:

 

 

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

以下错误的选项是?

## aop ### before ```cpp ``` ### after ```cpp ``` ## 答案 ```cpp class Solution { public: int row[9][9] = {0}, column[9][9] = {0}, grid[9][9] = {0}; void generate(int i, int j, vector> &board, bool &selved) { if (i > 8) { selved = true; return; } if (board[i][j] == '.') { int n = 3 * (i / 3) + j / 3; for (int k = 0; k < 9; k++) { if (!row[i][k] && !column[j][k] && !grid[n][k]) { row[i][k]++; column[j][k]++; grid[n][k]++; board[i][j] = k + '0' + 1; if (j == 8) generate(i + 1, 0, board, selved); else generate(i, j + 1, board, selved); if (!selved) { row[i][k]--; column[j][k]--; grid[n][k]--; board[i][j] = '.'; } } } } else { if (j == 8) generate(i + 1, 0, board, selved); else generate(i, j + 1, board, selved); } } void solveSudoku(vector> &board) { int i, j; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { if (board[i][j] == '.') continue; int num = board[i][j] - '0' - 1; row[i][num]++; column[j][num]++; grid[3 * (i % 3) + j % 3][num]++; } } bool selved = false; generate(0, 0, board, selved); } }; ``` ## 选项 ### A ```cpp class Solution { public: void solveSudoku(vector> &board) { int size = board.size(); vector> rows(size, vector(10)); vector> cols(size, vector(10)); vector> boxes(size, vector(10)); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if (board[i][j] != '.') { int num = board[i][j] - '0'; int idx = i / 3 * 3 + j / 3; rows[i][num] = true; cols[j][num] = true; boxes[idx][num] = true; } } } dfs(board, 0, rows, cols, boxes); } private: bool valid(int num, int row, int col, int idx, vector> &rows, vector> &cols, vector> &boxes) { return !rows[row][num] && !cols[col][num] && !boxes[idx][num]; } bool dfs(vector> &board, int size, vector> &rows, vector> &cols, vector> &boxes) { if (size == 9 * 9) { return true; } else { bool ok = false; int row = size / 9; int col = size % 9; int idx = row / 3 * 3 + col / 3; if (board[row][col] == '.') { for (int i = 1; i <= 9; i++) { if (valid(i, row, col, idx, rows, cols, boxes)) { board[row][col] = i + '0'; rows[row][i] = true; cols[col][i] = true; boxes[idx][i] = true; ok = dfs(board, size + 1, rows, cols, boxes); if (!ok) { rows[row][i] = false; cols[col][i] = false; boxes[idx][i] = false; board[row][col] = '.'; } } } } else { ok = dfs(board, size + 1, rows, cols, boxes); } return ok; } } }; ``` ### B ```cpp class Solution { public: void solveSudoku(vector> &board) { Dfs(board, 0); } private: bool flag = false; void Dfs(vector> &board, int n) { if (n > 0 && n <= 81) if (!JudgeIsNoWant(board, n - 1)) return; if (n >= 81) { flag = true; return; } int x = n / 9; int y = n % 9; if (board[x][y] != '.') Dfs(board, n + 1); else { for (int i = 1; i < 10; i++) { board[x][y] = i + 48; Dfs(board, n + 1); if (flag == true) return; board[x][y] = '.'; } } } bool JudgeIsNoWant(vector> &board, int n) { int x = n / 9; int y = n % 9; for (size_t i = 0; i < 9; i++) { if (board[x][i] == board[x][y] && i != y) return false; if (board[i][y] == board[x][y] && i != x) return false; } for (int i = x / 3 * 3; i < x / 3 * 3 + 3; i++) for (int j = y / 3 * 3; j < y / 3 * 3 + 3; j++) if (board[i][j] == board[x][y] && (i != x || j != y)) return false; return true; } }; ``` ### C ```cpp class Solution { public: int row[9][9], col[9][9], block[9][9]; void solveSudoku(vector> &board) { for (int i = 0; i < 9; ++i) { for (int j = 0; j < 9; ++j) { if (board[i][j] == '.') continue; int num = board[i][j] - '1'; row[i][num] = col[j][num] = block[i / 3 * 3 + j / 3][num] = 1; } } dfs(board, 0, 0); } bool dfs(vector> &board, int r, int c) { if (r > 8) return true; if (board[r][c] == '.') { for (int i = 0; i < 9; ++i) { if (row[r][i] || col[c][i] || block[r / 3 * 3 + c / 3][i]) continue; board[r][c] = i + 1 + '0'; row[r][i] = col[c][i] = block[r / 3 * 3 + c / 3][i] = 1; if (dfs(board, r + (c + 1) / 9, (c + 1) % 9)) return true; board[r][c] = '.'; row[r][i] = col[c][i] = block[r / 3 * 3 + c / 3][i] = 0; } } else return dfs(board, r + (c + 1) / 9, (c + 1) % 9); return false; } }; ```