37. 解数独
思路:建议直接看大佬的题解,用三个数组,来保存整个board的状态。很巧妙的用到了bitset来记录数字被选定的状态,进行了状态压缩。
题解还从最小的可选状态(i,j)出发。
需要注意的是row、col、ceil数组的构建,卡住我一个多小时,人都麻了。
class Solution {
public:
vector<bitset<9>> row,col;
vector<vector<bitset<9>>> ceil;
bitset<9> getNum(int i,int j){
return ~(row[i]|col[j]|ceil[i/3][j/3]);
}
vector<int> getPosition(vector<vector<char>>& board){
vector<int> v;
int minn=10;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]!='.') continue;
auto tmp=getNum(i,j);
if(tmp.count()<minn){
minn=tmp.count();
v={i,j};
}
}
}
if (v.empty()) return {}; // 确保有有效值返回
return v;
}
bool dfs(vector<vector<char>>& board,int ct){
if(ct==0) return true;
auto id=getPosition(board);
if(id.empty()) return false;
int x=id[0],y=id[1];
auto tmp=getNum(x,y);
for(int i=0;i<tmp.size();i++){
if(tmp[i]==1){
board[x][y]=i+'1';
row[x][i]=1;
col[y][i]=1;
ceil[x/3][y/3][i]=1;
if(dfs(board,ct-1)) return true;
board[x][y]='.';
row[x][i]=0;
col[y][i]=0;
ceil[x/3][y/3][i]=0;
}
}
return false;
}
void solveSudoku(vector<vector<char>>& board) {
row = vector<bitset<9>>(9, bitset<9>());
col = vector<bitset<9>>(9, bitset<9>());
ceil = vector<vector<bitset<9>>>(3, vector<bitset<9>>(3, bitset<9>()));
//进行预处理
int ct=0;
for(int i=0;i<board.size();i++){
for(int j=0;j<board[0].size();j++){
if(board[i][j]=='.'){
ct++;
}else{
int tmp=board[i][j]-'1';
row[i][tmp]=1;
col[j][tmp]=1;
ceil[i/3][j/3][tmp]=1;
}
}
}
cout<<ct;
dfs(board,ct);
}
};