• 经典递归回溯问题之——解数独(LeetCode 37)


    题目内容

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

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

    数字 1-9 在每一行只能出现一次。
    数字 1-9 在每一列只能出现一次。
    数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
    数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

    示例 1:

    在这里插入图片描述

    输入: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] 是一位数字或者 ‘.’
    题目数据 保证 输入数独仅有一个解

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/sudoku-solver
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路

    image.png

    这道题其实往简单了想,和八皇后问题可以说是一个思路。就是一个个的尝试,在循环中使用递归函数。只要后续回来了,就说明我们目前这个思路有问题,需要我们回过头来,重新尝试目前这个点位的选择,如果这个点位没有可以选择的了,就说明之前的选择就已经错了,我们直接回去重新尝试即可。

    这个代码的整体思路其实说不上多复杂,但是我在写的时候虽然看着是一次过,但是其实改了好久,就是因为代码的结果始终存在各种的问题,在没有意识到问题出现在哪里的时候,那些各种错误千奇百怪的,不过后来我意识到了错误的点之后很快就解决了。发现的契机就是我意识到,一些已经给定了的数也被改动了,而这在我们的代码中显然是不应该的。

    随后,我就反应过来,出现问题的点在于虽然给定数据的点位在当时第一次到的时候,我们设置好了叫他直接返回,但是在后面有问题了,返回到这个点之后,他会直接走到我们的循环里面,然后获得一个新的数据。这显然就错了。

    所以,我是用的另一个数组来记录和判定,不过也可以直接后面return,应该也是可以的。

    代码

    class Solution {
    public:
        int heng[9][10]={0};
        int shu[9][10]={0};
        int kuai[9][10]={0};
        int valid=0;
        int tu[9][9]={0};
    
        void dfs(vector<vector<char>>& board,int x,int y)
        {
            if(x==9){
                valid=1;
                // for(int i=0;i<9;i++){
                //     for(int j=0;j<9;j++){
                //         cout<
                //     }
                //     cout<
                // }
                return;
            }
            if(tu[x][y]==0){
                // cout<
                if(y==8){
                    dfs(board,x+1,0);  
                }
                else{
                    dfs(board,x,y+1);
                }
            }
            int hao=x/3*3+y/3;
            if(tu[x][y]==1){
                for(int i=1;i<10&&valid==0;i++){
                    if(heng[x][i]==0&&shu[y][i]==0&&kuai[hao][i]==0){
                        board[x][y]='0'+i;
                        // cout<
                        heng[x][i]=1;
                        shu[y][i]=1;
                        kuai[hao][i]=1;
                        if(y==8){
                            dfs(board,x+1,0);  
                        }
                        else{
                            dfs(board,x,y+1);
                        }
                        heng[x][i]=0;
                        shu[y][i]=0;
                        kuai[hao][i]=0;
                    }
                } 
            }
            
            // cout<<"chonglai"<
            return;
        }
    
        void solveSudoku(vector<vector<char>>& board) {
            for(int i=0;i<9;i++){
                for(int j=0;j<9;j++){
                    if(board[i][j]=='.'){
                        tu[i][j]=1;
                        continue;
                    }
                    int num=board[i][j]-'0';
                    heng[i][num]=1;
                    shu[j][num]=1;
                    int hao=i/3*3+j/3;
                    kuai[hao][num]=1;
                }
            }
            dfs(board,0,0);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
  • 相关阅读:
    LightMap 设置参数的介绍
    生产者消费者模型(linux下c语言实现)
    更换可执行文件glibc版本的某一次挣扎
    2023届春招实习-个人面试过程和面经分享
    北邮22级信通院数电:Verilog-FPGA(10)第十周实验 实现移位寄存器74LS595
    架构开发与优化咨询和实施服务
    Go 基础语法 轻松上手 goland~
    电源小白入门学习6——锂离子电池特性及充电电路
    【网页设计】基于HTML在线图书商城购物项目设计与实现
    Andorid复习
  • 原文地址:https://blog.csdn.net/weixin_51529433/article/details/126103488