37. 解数独
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
解题
数独问题用回溯法,对每一个待填写的位置遍历所有能填写的数,直到成功填写所有的空格为止;
解法1:暴力回溯
创建3*9个哈希表,存放每行每列和每个3 * 3方格里的数,防止重复填放;
isvalid函数判断该为止放t数会不会导致行列格有重复数字,若有则不填这个数,若无则可填入,若后面无法填写,则该步撤销;
终止条件——第9行填满,即i==9;
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
row.resize(9);
col.resize(9);
box.resize(9);
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
if(board[i][j]!='.')
{
row[i][board[i][j]]++;
col[j][board[i][j]]++;
box[i/3*3+j/3][board[i][j]]++;
}
}//初始化哈希表
traceback(board,0,0);
}
private:
vector<unordered_map<char,int>> row,col,box;
bool traceback(vector<vector<char>> & board,int i,int j)
{
if(j==9) return traceback(board,i+1,0);
if(i==9) return true;
if(board[i][j]!='.') return traceback(board,i,j+1);
for(int t='1';t<='9';t++)
{
if(isvalid(t,i,j)){
board[i][j]=t;
row[i][t]++;
col[j][t]++;
box[i/3*3+j/3][t]++;
if(traceback(board,i,j+1)) return true;
else {
board[i][j]='.';
row