Sudoku Solver

来源:互联网 发布:p51h战斗机数据 编辑:程序博客网 时间:2024/06/05 16:45

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