您的位置:首页 > 其它

LeetCode Sudoku Solver

2013-04-15 05:51 344 查看
56 ms 过large test

基本算法,有三个数组,分别记录每一行,每一列,每一个方块里面被填了的数,例如,如果第1行里,1已经被填了,那么

row[0][0] = 1,

这样,可以很快的测试对于board[i][j], 数字r是否可以填

if(row[i][r] == 0 && col[j][r] == 0 && square[i/3*3+j/3][r] == 0)

采用深度优先的search + backtrack,如果一个方块内所有的数字都不available,需要较快的backtrack,use a vector<> or a stack<> to do fast backtrack

when backtrack,need to recover row[i], col[j], square[i/3*3 + j/3] fast.

class Solution {

int rows[9][9];

int cols[9][9];

int squares[9][9];

void move_ahead(size_t & row, size_t & col){

    col ++;

    if(col == 9){

        col -= 9;

        row ++;

    }

}

bool place_a_number_start(size_t & row, size_t & col, 

                          size_t start_search, stack<pair<size_t, size_t>> &num,

                          vector<vector<char> > &board)

{

    for(size_t i=start_search; i<9; i++)

        if(rows[row][i] == 0 && cols[col][i] == 0 && squares[(row/3)*3+col/3][i] == 0){

            if(start_search == 0)

                num.push(pair<size_t, size_t>(row*9 + col, i));

            else

                num.top().second = i;           

            rows[row][i] = cols[col][i] = squares[(row/3)*3+col/3][i] = 1;

            board[row][col] = '1'+i;

            move_ahead(row, col);

            return true;

        }

    if(start_search != 0)

        num.pop();

    return false;

}

void clear_a_number(size_t & row, size_t & col, size_t pos, vector<vector<char> > &board){

    board[row][col] = '.';

    rows[row][pos] = cols[col][pos] = squares[(row/3)*3+col/3][pos] = 0;

}

public:

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

        // Start typing your C/C++ solution below

        // DO NOT write int main() function

        for(int i=0; i<9; i++){

            memset(rows[i], 0, sizeof(int)*9);

            memset(cols[i], 0, sizeof(int)*9);

            memset(squares[i], 0, sizeof(int)*9);

        }

        for(int i=0; i<9; i++){

            for(int j=0; j<9; j++){

                if(board[i][j] != '.'){

                    int pos = board[i][j] - '1';

                    rows[i][pos] = 1;

                    cols[j][pos] = 1;

                    squares[(i/3)*3+j/3][pos] = 1;

                }   

            }

        }

        stack<pair<size_t, size_t>> num;

        size_t row = 0, col = 0;

        while(row != 9){

            if(board[row][col] != '.'){

                move_ahead(row, col);

            } else {

                if(num.size() == 0){

                    if(!place_a_number_start(row, col, 0, num, board))

                        return;

                } else {

                    bool moved = false;

                    if(num.top().first == row*9 + col){

                        

                        moved = place_a_number_start(row, col, num.top().second + 1, num, board);

                    }else 

                        moved = place_a_number_start(row, col, 0, num, board);

                    if(moved == false){

                        if(num.size() > 0) {

                            row = num.top().first/9;

                            col = num.top().first%9;

                            clear_a_number(row, col, num.top().second, board);

                        } else 

                            return;

                    }

                }

            }

            

        }

        

    }

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode