题目描述:
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字
1-9
和字符'.'
。 - 你可以假设给定的数独只有唯一解。
- 给定数独永远是
9x9
形式的。
解题思路:
遍历所有空白格子,每个格子再遍历行列及其所在的九宫格,得到可以填的数字,再遍历所有数字;
遇到没有可填数字的情况则回溯到上一层,直到把所有格子填完即可。
代码:
执行用时: 4 ms, 在Sudoku Solver的C++提交中击败了95.52% 的用户
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
push(board, -1, 0);
}
bool push(vector<vector<char>>& board, int x, int y) {
//找空白格
while(true) {
if(++x == 9) {
x = 0;
if(++y == 9)
return true;
}
if(board[y][x] == '.')
break;
}
//找可填数字
bool nums[10] = {0};
for(int i=0; i<9; i++)
if(board[y][i] != '.')
nums[board[y][i] - '0'] = true;
for(int i=0; i<9; i++)
if(board[i][x] != '.')
nums[board[i][x] - '0'] = true;
for(int i=x - x % 3, ki=0; ki<3; i++, ki++)
for(int j=y - y % 3, kj=0; kj<3; j++, kj++)
if(board[j][i] != '.')
nums[board[j][i] - '0'] = true;
//dfs
for(int i=1; i<10; i++) {
if(!nums[i]) {
board[y][x] = '0' + i;
if(push(board, x, y))
return true;
}
}
//回溯
board[y][x] = '.';
return false;
}
};