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;
}
}
}
}
}
};
基本算法,有三个数组,分别记录每一行,每一列,每一个方块里面被填了的数,例如,如果第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第37之Sudoku Solver
- leetcode Sudoku Solver
- LeetCode--Sudoku Solver
- LeetCode : Sudoku Solver [java]
- leetcode 93: Sudoku Solver (uncompleted.)
- LeetCode Sudoku Solver
- leetcode Sudoku Solver
- LeetCode Sudoku Solver
- LeetCode "Sudoku Solver"
- leetcode 93: Sudoku Solver (uncompleted.)
- leetcode -- Sudoku Solver
- leetcode Sudoku Solver
- [LeetCode]37 Sudoku Solver
- leetcode Sudoku Solver
- 37. Sudoku Solver Leetcode Python
- LeetCode Sudoku Solver
- [leetcode]Sudoku Solver
- LeetCode Sudoku Solver
- LeetCode Sudoku Solver
- Leetcode | Valid Sudoku & Sudoku Solver