LeetCode 37:解数独

LeetCode 37:解数独

原题地址

基本思路

主要思路是深度优先搜索,依次填充每个空位。重点在于降低每次DFS的开销。我们尝试对空位填充数字时,要在尽可能短的时间内找到可以填充的数字。所以可以用一些辅助数组分别保存当前位置所在的行、列、九宫格中已有的数字,这样就不用实时检查所在行、列、九宫格中的其它数字。

代码

class Solution {
public:
    bool dfs(vector<vector<char>>& board, std::vector<std::vector<bool>>& rowVec,
    std::vector<std::vector<bool>>& colVec, std::vector<std::vector<bool>>& blockVec,
    std::vector<std::pair<int, int>> emptyPos, int thisEmpty)
    {
        if(emptyPos.size() == thisEmpty)    return true;

        int row = emptyPos[thisEmpty].first;
        int col = emptyPos[thisEmpty].second;
        int blockID = (row/3)*3 + col/3;
        
        std::vector<int> numVec;
        for(int num = 1; num <= 9; num++)
        {
            if(!rowVec[row][num] && !colVec[col][num] && !blockVec[blockID][num])
            {
                numVec.push_back(num);
            }
        }

        bool result = false;
        for(int i=0; i<numVec.size(); i++)
        {
            int num = numVec[i];
            board[row][col] = num+'0';
            rowVec[row][num] = true;
            colVec[col][num] = true;
            blockVec[blockID][num] = true;
            result = result || dfs(board, rowVec, colVec, blockVec, emptyPos, thisEmpty+1);
            if(result == true)
            {
                break;
            }
            else
            {
                board[row][col] = '.';
                rowVec[row][num] = false;
                colVec[col][num] = false;
                blockVec[blockID][num] = false;
            }     
        }
        return result;
    }
    void solveSudoku(vector<vector<char>>& board) {
        
        std::vector<std::vector<bool>> rowVec(9, std::vector<bool>(10, false)); 
        std::vector<std::vector<bool>> colVec(9, std::vector<bool>(10, false)); 
        std::vector<std::vector<bool>> blockVec(9, std::vector<bool>(10, false));
        std::vector<std::pair<int, int>> emptyPos;

        //初始化存储矩阵
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                if(board[i][j] != '.')
                {
                    int tmp = board[i][j]-'0';
                    rowVec[i][tmp] = true;
                    colVec[j][tmp] = true;

                    int blockID = (i/3)*3 + j/3;
                    blockVec[blockID][tmp] = true;
                }
                else
                {
                    emptyPos.push_back({i,j});
                }
            }
        }
        dfs(board, rowVec, colVec, blockVec, emptyPos, 0);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值