题目:Sudoku Solver
原题描述
原题链接:https://leetcode.com/problems/sudoku-solver/?tab=Description 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
给出一张数独表,完成填写。 空白部分用’.’表示,题目保证有且仅有唯一解。
思路
采用回溯法,假设数组按照从左到右从上到下的顺序扫描,每遇到一个空格,从1到9枚举出第一个能够满足当前位置合法的字符,然后扫描下一个空格进行枚举,一直到所有的空格都填满,则表示已经完成。如果当前空格枚举到9都不能合法,则把当前空格置为’.’,回溯到上一个空格,上一个空格的字符在原有的字符上加一,然后继续枚举出第一个能合法的字符,再继续往下,然后有问题则继续回溯,一直到所有空格都填满,或者第一个空格回溯到了9也不能满足为止(当然题目保证有唯一解,肯定可以填满。)
代码
class Solution {
public:
void solveSudoku(
vector<vector<char>>& board) {
vector<pair<int, int>> ve;
for(
int i =
0; i <
9; ++i) {
for(
int j =
0; j <
9; ++j) {
if(board[i][j] ==
'.') {
ve.push_back(
std::make_pair(i, j));
}
}
}
if(!ve.size())
return;
int len = ve.size(), index =
0;
while(
1) {
int row = ve[index].first, col = ve[index].second;
if(index ==
0 && board[row][col] ==
'9')
break;
if(index == len)
break;
if(board[row][col] ==
'.') {
board[row][col] =
'0';
}
board[row][col] +=
1;
while(board[row][col] <=
'9' && !isOk(board, row, col)) {
board[row][col] +=
1;
}
if(board[row][col] <=
'9') {
index++;
}
else{
board[row][col] =
'.';
index--;
}
}
}
private:
bool isOk(
vector<vector<char>>& board,
int row,
int col) {
for(
int i =
0; i <
9; ++i) {
if(i == row)
continue;
if(board[i][col] == board[row][col])
return false;
}
for(
int i =
0; i <
9; ++i) {
if(i == col)
continue;
if(board[row][i] == board[row][col])
return false;
}
int stR = row /
3, stC = col /
3;
for(
int i = stR *
3; i < stR *
3 +
3; ++i) {
for(
int j = stC *
3; j < stC *
3 +
3; ++j) {
if(i == row && j == col)
continue;
if(board[i][j] == board[row][col])
return false;
}
}
return true;
}
};
优化
这个解法还可以优化一下,比如在所有空格都是初始化的时候对每个空格都进行一次枚举,确定每个空格能在初始状态下能够满足的字符有哪几个,这样就不用每次都从’1’到’9’开始枚举啦,具体就让读者们自己试着写写吧
转载请注明原文地址: https://ju.6miu.com/read-35352.html