思路:哈希表+回溯
解数独维护以下哈希表
- 行关于值的哈希表rows[9][9]
- 列关于值的哈希表columns[9][9]
- 3*3表格关于值的哈希表squares[3][3][9]
N皇后维护以下哈希表
- 列的哈希表 unordered_set/columns
- 横纵坐标和的哈希表 unordered_set/add
- 横纵坐标差的哈希表 unordered_set/reduce
解数独代码:
class Solution {
public:
bool rows[9][9];
bool columns[9][9];
bool squares[3][3][9];
vector<pair<int,int>>spaces;
int finished;
void solveSudoku(vector<vector<char>>& board) {
memset(rows,false,sizeof(rows));
memset(columns,false,sizeof(columns));
memset(squares,false,sizeof(columns));
finished = 0;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.'){
spaces.push_back(make_pair(i,j));
}
else{
int value = board[i][j]-'0'-1;
rows[i][value] = true;
columns[j][value] = true;
squares[i/3][j/3][value] = true;
}
}
}
dfs(0,board);
}
void dfs(int idx,vector<vector<char>>& board){
if(idx == spaces.size()){
finished = 1;
return;
}
int x = spaces[idx].first;
int y = spaces[idx].second;
for(int v=0;v<9;v++){
char value = v +'0'+1;
if(rows[x][v]==false&&columns[y][v]==false&&squares[x/3][y/3][v]==false&&!finished){
board[x][y]=value;
rows[x][v] = true;
columns[y][v] = true;
squares[x/3][y/3][v] = true;
dfs(idx+1,board);
rows[x][v] = false;
columns[y][v] = false;
squares[x/3][y/3][v] = false;
}
}
}
};
N皇后问题
class Solution {
public:
unordered_set<int>columns;
unordered_set<int>add;
unordered_set<int>reduce;
vector<vector<string>>res;
vector<string>v;
vector<vector<string>> solveNQueens(int n) {
string str;
for(int i=0;i<n;i++){
str += '.';
}
v = vector<string>(n,str);
dfs(0,n);
return res;
}
void dfs(int i,int n){
if(i==n){
res.push_back(v);
return;
}
for(int j=0;j<n;j++){
if(columns.find(j)==columns.end()&&add.find(i+j)==add.end()&&reduce.find(i-j)==reduce.end()){
columns.insert(j);
add.insert(i+j);
reduce.insert(i-j);
v[i][j]='Q';
dfs(i+1,n);
columns.erase(j);
add.erase(i+j);
reduce.erase(i-j);
v[i][j]='.';
}
}
}
};
注意点:
1.如何记录解数独的3*3表格关于值的哈希表squares[3][3][9]
2.解数独是原地操作找到时因立即停下,否则会改变board结果