编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字
1-9
和字符'.'
。 - 你可以假设给定的数独只有唯一解。
- 给定数独永远是
9x9
形式的。
做这题的时候,回溯不太熟练,此代码有测试语句,不可以直接复制到leetcode
import java.util.HashSet;
import java.util.Scanner;
public class 解数独 {
static int t=0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
char[][] ch = new char[9][9];
for(int i=0;i<9;i++)
{
ch[i] = in.next().toCharArray();
}
f(ch,0);
System.out.println("\n\n\nsum:"+t);
}
public void solveSudoku(char[][] board) {
f(board,0);
}
static boolean has = false;
static void f(char[][] board,int m)
{
if(has==true)
return;
if(m==81)
{
// t++;
//打印
// for(int i=0;i<9;i++)
// {
// for(int j=0;j<9;j++)
// {
// System.out.print(board[i][j]+" ");
// }
// System.out.println();
// }
// System.out.println();
has=true;
return;
}
int i = m/9;
int j = m%9;
if(board[i][j]!='.')
{
f(board,m+1);
return;
}
for(int k=1;k<=9;k++)
{
board[i][j]=(char) ('0'+k);
if(is(board,i,j))
f(board,m+1);
board[i][j]='.';
}
}
private static boolean is(char[][] board,int m,int n) {
// HashSet<Character> set = new HashSet<>();
for(int i=0;i<9;i++)
{
if(board[m][i]!='.')
{
// if(!set.contains(board[m][i]))
// set.add(board[m][i]);
// else
// return false;
if(board[m][i]==board[m][n] && n!=i)
return false;
}
}
// set.clear();
for(int i=0;i<9;i++)
{
// if(board[i][n]!='.')
// {
// if(!set.contains(board[i][n]))
// set.add(board[i][n]);
// else
// return false;
// }
if(board[i][n]==board[m][n] && m!=i)
return false;
}
// set.clear();
for(int i=3*(m/3);i<3+3*(m/3);i++)
{
for(int j=3*(n/3);j<3+3*(n/3);j++)
{
if(board[i][j]!='.')
{
// if(!set.contains(board[i][j]))
// set.add(board[i][j]);
// else
// return false;
if(board[i][j]==board[m][n] && !(i==m&&j==n))
return false;
}
}
}
// set.clear();
return true;
}
}