DFS Leetcode 037解数独

题解

https://www.acwing.com/solution/content/8689/

地址

https://leetcode-cn.com/problems/sudoku-solver/submissions/

描述

在这里插入图片描述

思想

枚举每个点,如果是空格,就选择合适的点进行填数,然后不断往下搜索,直到填完所有数(x == n)时,dfs从里不断返回true,直到退到最外面的递归函数位置
这里bool型dfs的好处是可以防止找到一种方案了,还去恢复现场
注意:这里不同于n皇后问题,这里是修改原数组(修改成一种可行解即可),而皇后问题是输出结果,不是修改原数组

代码

class Solution {
    
    
public:
    // row[x][u]表示第x行是否已经填过数字u(0-8)
    // col[y][u]表示第y行是否已经填过数字u(0-8)
    // box[x / 3][y / 3][u]表示第[x/3,y/3]个box是否已经填过数字u(0-8)
    bool row[9][9],col[9][9],box[3][3][9];
    void solveSudoku(vector<vector<char>>& b) {
    
    
        //首先进行初始化
        memset(row,0,sizeof row);
        memset(col,0,sizeof col);
        memset(box,0,sizeof box);
        //将板子中已经填入的数记录下来
        for(int i=0;i<9;i++){
    
    
            for(int j=0;j<9;j++){
    
    
                if(b[i][j]!='.'){
    
    
                    int t=b[i][j]-'1';
                    row[i][t]=col[j][t]=box[i/3][j/3][t]=true;
                }
            }
        }
        dfs(b,0,0);
    }
    bool dfs(vector<vector<char>> &b,int x,int y){
    
    
        if(y==9) x++,y=0;
        //所有的格子都填完了
        if(x==9) return true;
        //这个格子已经填好了,跳过
        if(b[x][y]!='.')  return dfs(b,x,y+1);
        //从1~9中选择该放进哪个数
        for(int i=0;i<9;i++){
    
    
            //这个数在行列还有3*3宫格中都没出现过
            if(!row[x][i]&&!col[y][i]&&!box[x/3][y/3][i]){
    
    
                b[x][y]=i+'1';
                row[x][i]=col[y][i]=box[x/3][y/3][i]=true;
                // 如果下面搜索后是对的,就提前返回,不恢复现场(因为要修改board);
                // 如果是false就恢复现场(这个方法很巧妙)
                if(dfs(b,x,y+1)) return true;
                //回溯
                b[x][y]='.';
                row[x][i] = col[y][i] = box[x / 3][y / 3][i] = false;
            }
        }
        //9个数都试过了还不行,就return false;
        return false;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_52934831/article/details/121470918