首先可以看下昨天的 Leetcode #36. Valid Sudoku 数独游戏验证 解题报告
数独的求解,这道题可以假设给定的这个是正确的
做法就只能是暴力的回溯了。。
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.
/** * 方法是回溯,用各个标志位来标志是否存在冲突 * 如果数字原来就有了,那么就跳过处理 * 因为答案只有一个,所以一旦找到,就要立马跳出递归(如果你用的是栈实现的回溯可能会好处理些) * 总之就是仔细些。。。我一次写过的,而且耗时貌似还很短。。。 * * 我没用题目提示的哈希,我用了数组去判断,因为这样快!!!,还有char数组还是先变成int数组吧,不然算起来很累。。 * * */
public class Solution {
//各行各列的标志位
boolean col[][]; //列
boolean row[][]; //行
boolean zone[][]; //九宫格内
char result[][];
//转换成正数
int[][] tmp;
boolean flag;
public void find(int index){
if(index==81){
flag=true;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
result[i][j]=(char)('0'+tmp[i][j]);
}
}
}
if(flag)
return;
int i=index/9,j=index%9;
if(tmp[i][j]==0){ // 此时等于0代表原来的是. 还没有数字进行填充,才进行运算,否则直接到下一个了
for(int k=1;k<=9;k++){
if(col[j][k]==false && row[i][k]==false && zone[(i/3)*3+j/3][k]==false){
/** * 递归的时候注意状态的改变,进入递归前先改变状态,跳出时要修正状态回来*/
col[j][k]=true;
row[i][k]=true;
zone[(i/3)*3+j/3][k]=true;
tmp[i][j]=k;
find(index+1);
tmp[i][j]=0;
col[j][k]=false;
row[i][k]=false;
zone[(i/3)*3+j/3][k]=false;
}
}
}
else{
find(index+1);
}
}
public void solveSudoku(char[][] board) {
int i,j;
result=board;
flag=false;
col=new boolean[9][10];
row=new boolean[9][10];
zone=new boolean[9][10];
tmp=new int[9][9];
//第一遍的扫描设置初始位置和标志位
for(i=0;i<9;i++){
for(j=0;j<9;j++){
if(board[i][j]!='.'){
tmp[i][j]=board[i][j]-'0';
col[j][tmp[i][j]]=true;
row[i][tmp[i][j]]=true;
zone[(i/3)*3+j/3][tmp[i][j]]=true;
}
}
}
find(0);
}
}