Sudoku Solver

Method 1: DFS (248 ms)

class Solution {
public:
    void solveSudoku(vector<vector<char> > &board) {
        solveSudoku1(board);
    }
    
    bool solveSudoku1(vector<vector<char> > &board)
    {
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                if(board[i][j] == '.')
                {
                    for(int k=0; k<9; k++)
                    {
                        board[i][j] = '1'+k;
                        if(isValid(board, i, j) && solveSudoku1(board))
                            return true;
                        board[i][j] = '.';
                    }
                    return false;
                }
            }
        }
        return true;
    }
    
    bool isValid(vector<vector<char> > &board, int i, int j)
    {
        for(int col = 0; col < 9; col++)
            if(col != j && board[i][col] == board[i][j])
                return false;
        
        for(int row = 0; row < 9; row++)
            if(row != i && board[row][j] == board[i][j])
                return false;
        
        int gridRow = i/3;
        int gridCol = j/3;
        
        for(int row = gridRow*3; row < gridRow*3+3; row++)
        {
            for(int col = gridCol*3; col < gridCol*3+3; col++)
            {
                if(row != i && col != j && board[row][col] == board[i][j])
                    return false;
            }
        }
        return true;
    }
};

Method 2: improve the validation method using hash map. ( 100 ms)

class Solution {
public:
    int rowhash[9];
    int colhash[9];
    int blockhash[9];
    
    void solveSudoku(vector<vector<char> > &board) {
        memset(rowhash, 0, sizeof(rowhash));
        memset(colhash, 0, sizeof(colhash));
        memset(blockhash, 0, sizeof(blockhash));
        
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                if(board[i][j] != '.')
                {
                    setMap(board, i, j);
                }
            }
        }
        solveSudoku1(board);
    }
    
    bool solveSudoku1(vector<vector<char> > &board)
    {
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                if(board[i][j] == '.')
                {
                    for(int k=0; k<9; k++)
                    {
                        board[i][j] = '1'+k;
                        if(isValid(board, i, j))
                        {
                            setMap(board, i, j);
                            if(solveSudoku1(board)) return true;
                            resetMap(board, i, j);
                        }
                        board[i][j] = '.';
                    }
                    return false;
                }
            }
        }
        return true;
    }
    
    bool isValid(vector<vector<char> > &board, int i, int j)
    {
        if((rowhash[i] >> (board[i][j]-'1'))&1) return false;
        if((colhash[j] >> (board[i][j]-'1'))&1) return false;
        
        int gridRow = i/3;
        int gridCol = j/3;
        if((blockhash[gridRow*3+gridCol] >> (board[i][j]-'1')) & 1) return false;
        
        return true;
    }
    
    void setMap(vector<vector<char> > &board, int i, int j)
    {
        rowhash[i] |= (1 << (board[i][j]-'1'));
        colhash[j] |= (1 << (board[i][j]-'1'));
                    
        int gridRow = i/3;
        int gridCol = j/3;
        blockhash[gridRow*3+gridCol] |= (1 << (board[i][j]-'1'));
    }
    
    void resetMap(vector<vector<char> > &board, int i, int j)
    {
        rowhash[i] &= ~(1 << (board[i][j]-'1'));
        colhash[j] &= ~(1 << (board[i][j]-'1'));
                    
        int gridRow = i/3;
        int gridCol = j/3;
        blockhash[gridRow*3+gridCol] &= ~(1 << (board[i][j]-'1'));
    }
};

Method 3: non-recursion DFS with stack. (48 ms)

class Solution {
public:
    int rowhash[9];
    int colhash[9];
    int blockhash[9];
    
    void solveSudoku(vector<vector<char> > &board) {
        memset(rowhash, 0, sizeof(rowhash));
        memset(colhash, 0, sizeof(colhash));
        memset(blockhash, 0, sizeof(blockhash));
        
        vector<pair<int, int> > empty;
        empty.push_back(make_pair(-1, -1));
        for(int i=0; i<9; i++)
        {
            for(int j=0; j<9; j++)
            {
                if(board[i][j] != '.')
                {
                    setMap(i, j, (board[i][j]-'0'));
                }
                else
                    empty.push_back(make_pair(i,j));
            }
        }
        
        vector<pair<int, int> > stack;
        vector<pair<int, int> > path;
        
        //push back the dummy element index
        stack.push_back(make_pair(0, -1));
        
        int idx, val, posX, posY;
        
        while(!stack.empty())
        {
            idx = stack.back().first;
            val = stack.back().second;
            path.push_back(make_pair(idx, val));
            
            if(idx > 0)
            {
                posX = empty[idx].first;
                posY = empty[idx].second;
                
                board[posX][posY] = ('0' + val);
                setMap(posX, posY, val);   
            }
            
            if(path.size() == empty.size())
                break;
        
            pair<int, int> pos = empty[idx+1];
                
            for(int i=1; i<=9; i++)
            {
                if(isValid(pos.first, pos.second, i))
                    stack.push_back(make_pair(idx+1, i));
            }
            
            while(!stack.empty() && stack.back() == path.back())
            {
                idx = path.back().first;
                val = path.back().second;
                if(idx > 0)
                {
                    posX = empty[idx].first;
                    posY = empty[idx].second;
                    
                    board[posX][posY] = '.';
                    resetMap(posX, posY, val);
                }
                stack.pop_back();
                path.pop_back();
            }
        }
    }
    
    bool isValid(int i, int j, int value)
    {
        if((rowhash[i] >> value) & 1) return false;
        if((colhash[j] >> value) & 1) return false;

        if((blockhash[(i/3)*3+j/3] >> value) & 1) return false;
        
        return true;
    }
    
    void setMap(int i, int j, int value)
    {
        rowhash[i] |= (1 << value);
        colhash[j] |= (1 << value);
    
        blockhash[(i/3)*3+j/3] |= (1 << value);
    }
    
    void resetMap(int i, int j, int value)
    {
        rowhash[i] &= ~(1 << value);
        colhash[j] &= ~(1 << value);
    
        blockhash[(i/3)*3+j/3] &= ~(1 << value);
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值