您的位置:首页 > 其它

【LeetCode】Sudoku Solver

2014-06-10 21:03 253 查看
题目描述:

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character
'.'
.

You may assume that there will be only one unique solution.



A sudoku puzzle...



...and its solution numbers marked in red.
两种解法,都是DFS。
1、排除法,先对整个矩阵进行处理,记录下每个行、列、块里没有出现的值,这样在某个空位可以输入的值就是他所在位置的行、列、块的公共元素。这样效率相对较高,缺点是空间占用比较多,算就不具体算了……

2、由上一题引申出来,对每个位置填上数字然后验证是否是合法数独。当然不需要验证整个矩阵,只要验证行列块就好了。

代码如下:

方法一(153ms):

class Solution {
public:
void solveSudoku(vector<string> &board) {
unordered_set<char> num({ '1', '2', '3', '4', '5', '6', '7', '8', '9' });
vector<unordered_set<char>> m(9, num), n(9, num), B(9, num);
for (int i = 0; i < 9;i++)
for (int j = 0; j < 9; j++)
if (board[i][j] != '.')
m[i].erase(board[i][j]);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (board[j][i] != '.')
n[i].erase(board[j][i]);
for (int i = 0; i < 9;i+=3)
for (int j = 0; j < 9; j += 3){
int index = i / 3 * 3 + j / 3;
for (int k = i; k < i + 3; k++)
for (int l = j; l < j + 3; l++)
if (board[k][l] != '.')
B[index].erase(board[k][l]);
}
getSolution(board, m, n, B);
}
bool getSolution(vector<string> &board, vector<unordered_set<char>> &m, vector<unordered_set<char>> &n, vector<unordered_set<char>> &B){
int i(0), j(0);
for (i = 0; i < 9; i++){
for (j = 0; j < 9; j++)
if (board[i][j] == '.')
break;
if (j < 9)
break;
}
if (i >= 9)
return true;
vector<char> val;
int b = i / 3 * 3 + j / 3;
for (unordered_set<char>::iterator iter = m[i].begin(); iter != m[i].end(); iter++)
if (n[j].count(*iter) && B[b].count(*iter))
val.push_back(*iter);
if (val.empty())
return false;
for (int k = 0; k < val.size(); k++){
char c = val[k];
m[i].erase(c);
n[j].erase(c);
B[b].erase(c);
board[i][j] = c;
if (getSolution(board, m, n, B))
return true;
m[i].insert(c);
n[j].insert(c);
B[b].insert(c);
board[i][j] = '.';
}
return false;
}
};


方法二(236ms,网上抓来的代码):

class Solution {
public:
bool isValidSudoku(vector<vector<char> > &board, int x, int y) {
int row, col;

// Same value in the same column?
for (row = 0; row < 9; ++row) {
if ((x != row) && (board[row][y] == board[x][y])) {
return false;
}
}

// Same value in the same row?
for (col = 0; col < 9; ++col) {
if ((y != col) && (board[x][col] == board[x][y])) {
return false;
}
}

// Same value in the 3 * 3 block it belong to?
for (row = (x / 3) * 3; row < (x / 3 + 1) * 3; ++row) {
for (col = (y / 3) * 3; col < (y / 3 + 1) * 3; ++col) {
if ((x != row) && (y != col) && (board[row][col] == board[x][y])) {
return false;
}
}
}

return true;
}

bool internalSolveSudoku(vector<vector<char> > &board) {
for (int row = 0; row < 9; ++row) {
for (int col = 0; col < 9; ++col) {
if ('.' == board[row][col]) {
for (int i = 1; i <= 9; ++i) {
board[row][col] = '0' + i;

if (isValidSudoku(board, row, col)) {
if (internalSolveSudoku(board)) {
return true;
}
}

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

return false;
}
}
}

return true;
}

void solveSudoku(vector<vector<char> > &board) {
internalSolveSudoku(board);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: