Valid Sudoku
1、题目:
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character ‘.’.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
2、代码:
起初,天真的我以为有效与否,看他能不能解出来,结果老是超时,后来还百度一下,难道有更精妙的解法。看了几个帖子后发现都是递归啊!!!后来扫了一下别人的代码发现别人的怎么这么简单,慢着,竟然没有递归!!!结果再看题目,特别是把note翻译了一下,有效的不一定有解,一万个奔腾那个。于是就三个类别判断了一下,竟然是这样!!!
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
bool bflag[10];
for(int j=0;j<9;++j)//水平,横向
{
for(int i=1;i<10;++i)
{
bflag[i]=false;
}
for(int i=0;i<9;++i)
{
if(board[j][i]!='.'&&bflag[board[j][i]-48])
{
return false;
}
else if(board[j][i]!='.')
{
bflag[board[j][i]-48]=true;
}
}
}
for(int j=0;j<9;++j)//竖直
{
for(int i=1;i<10;++i)
{
bflag[i]=false;
}
for(int i=0;i<9;++i)
{
if(board[i][j]!='.'&&bflag[board[i][j]-48])
{
return false;
}
else if(board[i][j]!='.')
{
bflag[board[i][j]-48]=true;
}
}
}
for(int fy=0;fy<3;++fy)
{
for(int fx=0;fx<3;++fx)
{
for(int i=1;i<10;++i)
{
bflag[i]=false;
}
for(int j=fy*3;j<(fy+1)*3;++j)
{
for(int i=fx*3;i<(fx+1)*3;++i)
{
if(board[j][i]!='.'&&bflag[board[j][i]-48])
{
return false;
}
else if(board[j][i]!='.')
{
bflag[board[j][i]-48]=true;
}
}
}
}
}
return true;
}
};
当然了,这个也有要注意的地方,一行判断完再判断下一行时候要对数组全部置false,列和子格也是的,否则,又是许久肉眼找bug。
Sudoku Solver
1、题目:
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.
2、代码:
在上个题目的折腾中,我的这个题目基本完工,所以很快就开始测试了。
class Solution {
public:
bool isFill(vector<vector<char>>& board)//满员判断
{
for(int j=0;j<9;++j)
{
for(int i=0;i<9;++i)
{
if(board[j][i]=='.')
{
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
bool flag[10];
for(int i=1;i<10;++i)
{
flag[i]=false;
}
int i=0,j=0;
for(j=0;j<9;++j)
{
for(i=0;i<9&&board[j][i]!='.';++i);
if(i<9) break;
}
if(j==9&&i==9) //fill exit
{
return;
}
for(int t=0;t<9;++t)//水平,横向
{
if(board[j][t]!='.'&&(!flag[board[j][t]-48]))
{
flag[board[j][t]-48]=true;
}
}
for(int t=0;t<9;++t)//竖直
{
if(board[t][i]!='.'&&(!flag[board[t][i]-48]))
{
flag[board[t][i]-48]=true;
}
}
int fx=(i/3)*3,fy=(j/3)*3;
for(int t=fy;t<fy+3;++t)
{
for(int k=fx;k<fx+3;++k)
{
if(board[t][k]!='.'&&(!flag[board[t][k]-48]))
{
flag[board[t][k]-48]=true;
}
}
}
int t=0;
while(!isFill(board))
{
++t;
for(;t<10&&flag[t];++t);
if(t==10)
{
board[j][i]='.';
return;
}
board[j][i]=t+48;
solveSudoku(board);
}
}
};
3、总结:
A、退出递归的条件,已经填满或是当前位置没有可填数字。
B、哈希表要flag[10],数字是1–9。
C、满员判断函数,确定是否填满,决定结束与否。
D、如果此数填入,在后面发现无法填满时候,要将此数及后面的数还原成没有数的状态,如
if(t==10)
{
board[j][i]='.';
return;
}
E、哈希表一个就够了,在三类情况都对他进行查询和赋值。
F、int fx=(i/3)*3,fy=(j/3)*3;这个似乎要记一下,i/3表示横向第几个子格,是整数,再乘3定位。
实际执行
代码就不贴了,把上面的改一下就可以了。