• LeetCode 037. 解数独 DFS


    地址 https://leetcode-cn.com/problems/sudoku-solver/

    编写一个程序,通过填充空格来解决数独问题。
    
    一个数独的解法需遵循如下规则:
    
    数字 1-9 在每一行只能出现一次。
    数字 1-9 在每一列只能出现一次。
    数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
    空白格用 '.' 表示。
    
    提示:
    
    给定的数独序列只包含数字 1-9 和字符 '.' 。
    你可以假设给定的数独只有唯一解。
    给定数独永远是 9x9 形式的。

        

    算法1
    暴力DFS 可以考虑自行添加剪枝

    每个空格尝试填写数字 并检查该数字是否和行列九宫的其他数字冲突
    无冲突情况下全部填写完毕 即可

    C++ 代码

    class Solution {
    public:
        //记录九行九列九宫格 中1~9有没出现 
        //用于检测尝试填写的数字是否正确
        int Row[10][10];
        int Col[10][10];
        int Box[10][10];
    
        //初始化 填写数字的位置 在相应的数组记录中也要填写标记
        void Init(const vector<vector<char>>& board) {
            memset(Row, 0, sizeof(Row[0][0]) * 10 * 10);
            memset(Col, 0, sizeof(Col[0][0]) * 10 * 10);
            memset(Box, 0, sizeof(Box[0][0]) * 10 * 10);
    
            for (int r = 0; r < 9; r++) {
                for (int c = 0; c < 9; c++) {
                    if (board[r][c] != '.') {
                        int n = board[r][c] - '0';
                        Row[r][n] = 1;
                        Col[c][n] = 1;
                        Box[r / 3 * 3 + c / 3][n] = 1;
                    }
                }
            }
            return;
        }
    
        //根据行列宫的数组记录 查看在当前位置填写数字是否有冲突
        bool check(int n, int row, int col) {
            if (Row[row][n] != 1 && Col[col][n] != 1 &&
                Box[row / 3 * 3 + col / 3][n] != 1) {
                return true;
            }
    
            return false;
        }
    
        //填写数字后要修改相应的行列宫的记录
        void Fill(vector<vector<char>>& board,int n, int x, int y)
        {
            board[x][y] = n+'0';
    
            Row[x][n] = 1;
            Col[y][n] = 1;
            Box[x / 3 * 3 + y / 3][n] = 1;
    
        }
    
        //还原数字 回复相应的行列宫的记录
        void Restore(vector<vector<char>>& board,int n, int x, int y)
        {
            board[x][y] = '.';
    
            Row[x][n] = 0;
            Col[y][n] = 0;
            Box[x / 3 * 3 + y / 3][n] = 0;
        }
    
        //DFS 深度搜索进行填写数字的尝试
        bool Dfs(vector<vector<char>>& board, int x, int y)
        {
            if (y > 8) { y = 0; x++; }
            //设置终止条件
            if (x > 8) return true;
    
            if (board[x][y] == '.') {
                //尝试填充数字
                for (int n = 1; n <= 9; n++) {
                    if (check(n, x, y)) {
                        Fill(board, n, x, y);
                        y++; 
                        if (true == Dfs(board, x, y)) {
                            return true;
                        }
                        //还原
                        y--;
                        Restore(board, n, x, y);
                    }
                }
            }
            else {
                y++;
                if (true == Dfs(board, x, y)) {
                    return true;
                }
            }
    
            return false;
        }
    
        void solveSudoku(vector<vector<char>>& board) {
            Init(board);
    
            Dfs(board,0,0);
        }
    };
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Qt状态机实例
    <STL> accumulate 与 自定义数据类型
    <STL> 容器混合使用
    散列表(C版)
    Canonical 要将 Qt 应用带入 Ubuntu
    <STL> set随笔
    C++ 文件流
    视频播放的基本原理
    <STL> pair随笔
    c++ 内存存储 解决char*p, char p[]的问题
  • 原文地址:https://www.cnblogs.com/itdef/p/14119821.html
Copyright © 2020-2023  润新知