leetcode 37 解数独
一、问题描述
二、解题思路
整体思路
画出本题的决策树,可以采用回溯+剪枝的方法来解决这个问题。本题的剪枝策略与leetcode36有效的数独策略一致。leetcode 36 有效的数独-CSDN博客
具体思路
(1)函数功能:dfs函数用于从(row,col)开始,尝试填数字解出数独;
(2)递归出口:当row==9&&col==0,将found更新为true,直接return;
(3)函数体:
<1>在判断是否抵达递归出口之前,需要判断是否需要换行;
<2>如果当前位置的字符为数字字符,就dfs处理col+1位置;
<3>如果当前位置的字符为'.',就从'1'开始到'9'尝试填写这个位置,填写合法,就将当前位置对应的Col、Row、grid值赋值为true,再dfs处理col+1位置;
<4>如果找到答案了,就直接return。如果这里不return,函数回溯完成后,board会恢复到初始题目给的状态;
<5>否则,就回溯恢复现场;
三、代码实现
class Solution {bool Col[9][9]={false};bool Row[9][9]={false};bool grid[3][3][9]={false};bool found=false;public:void solveSudoku(vector<vector<char>>& board) {//遍历board,初始化三个bool数组for(int row=0;row!=9;row++)for(int col=0;col!=9;col++){if(board[row][col]!='.'){char c=board[row][col];Col[col][c-'1']=true;Row[row][c-'1']=true;grid[row/3][col/3][c-'1']=true;}}dfs(0,0,board);}void dfs(int row,int col,vector<vector<char>>& board){if(col==9){row++;col=0;}//递归出口if(row==9&&col==0) {found=true;return ;}//如果当前位置为数字字符if(board[row][col]!='.') dfs(row,col+1,board);//如果当前位置不为数字字符else{for(int num=0;num!=9;num++){char c=num+'1';if(!Col[col][num]&&!Row[row][num]&&!grid[row/3][col/3][num]){board[row][col]=c;Col[col][num]=Row[row][num]=grid[row/3][col/3][num]=true;dfs(row,col+1,board);if(found) return;//恢复现场board[row][col]='.';Col[col][num]=Row[row][num]=grid[row/3][col/3][num]=false;}}}}
};