leetcode 37 Sudoku Solver

class Solution {
public: 
    typedef vector<vector<char> >::size_type sz;
    typedef set<char>::iterator Sit;

    void solveSudoku(vector<vector<char>>& board) {

        sz size = board.size();

        // initialize the flags
        set<char> tmp;
        for(int i = 1; i < 10; ++i) {
            tmp.insert('0' + i);
        }

        rflag = vector<set<char> >(size, tmp);
        cflag = vector<set<char> >(size, tmp);
        bflag = vector<set<char> >(size, tmp);

        for (sz i = 0; i < size; ++i) {
            for (sz j = 0; j < size; ++j) {
                char ch = board[i][j];
                if (ch != '.') {
                    rflag[i].erase(ch);
                    cflag[j].erase(ch);
                    bflag[j / 3 * 3 + i / 3].erase(ch);
                }
            }
        }

        solve(board, 0);
        return;
    }

private:

    // mark every row
    vector<set<char> > rflag;

    // mark every column
    vector<set<char> > cflag;

    // mark every box
    vector<set<char> > bflag;

    bool solve(vector<vector<char>>& board, sz ir) {
        sz size = board.size();

         for (sz i = ir; i < size; ++i) {
            for (sz j = 0; j < size; ++j){
                char ch = board[i][j];
                if (ch == '.') {
                    set<char> vals(rflag[i]);
                    for (Sit it = vals.begin(); it != vals.end();) {
                        if (cflag[j].find(*it) == cflag[j].end() 
                            || bflag[j / 3 * 3 + i / 3].find(*it) == bflag[j / 3 * 3 + i / 3].end()){ // 取共有元素
                            vals.erase(*it++);
                        } else
                            ++it;
                    }

                    if (vals.empty()) {
                        return false;
                    }

                    for (Sit it = vals.begin(); it != vals.end(); ++it) {        
                        board[i][j] = *it;
                        rflag[i].erase(*it);
                        cflag[j].erase(*it);
                        bflag[j / 3 * 3 + i / 3].erase(*it);

                        if (solve(board, i) == false) {
                            rflag[i].insert(*it);
                            cflag[j].insert(*it);
                            bflag[j / 3 * 3 + i / 3].insert(*it);
                        } else {
                            return true;
                        }
                    }

                    board[i][j] = '.'; // 标回去
                    return false;
                }
            }
        }
        return true;    // end
    }
};

参考后

class Solution {
public:

    void solveSudoku(vector<vector<char>>& board) {

        solve(board, 0);
    }

private:
    bool solve(vector<vector<char> >& board, size_t r) {
        size_t size = board.size();

        for (size_t i = r; i < size; ++i) {
            for (size_t j = 0; j < size; ++j) {
                char ch = board[i][j];
                if (ch == '.') {
                    for (int k = 1; k <= 9; ++k) {
                        char val = '0' + k;
                        if (isValid(board, i, j, val)) {
                            board[i][j] = val;
                            if (solve(board, i) == true) 
                                return true;
                        }
                    }
                    board[i][j] = '.';
                    return false;
                }

            }
        }
        return true; // fill all the empty, all the solve is end
    }

    bool isValid(vector<vector<char> >& board, size_t row, size_t col, char c) {
        size_t size = board.size();
        size_t val = 'c' - '0';

        for (size_t i = 0; i < size; ++i) {

            // check row
            // check column
            // check block
            if (board[i][col] == c || board[row][i] == c || 
                board[(row / 3 * 3 + col / 3) / 3  * 3 + i / 3][(row / 3 * 3 + col / 3) % 3 * 3 + i % 3] == c)
                return false;
        }
        return true;  
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值