8、解数独
题目描述:
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
这道题的难度比较大,自己弄了很长时间,首先就是递归然后你需要根据后面能不能放下1-9这9个字符来进行回溯,这点很重要,数据结构和那道判断是否是合法数独的数据结构一样,代码如下:
class Solution {
public void solveSudoku(char[][] board) {
if(board == null || board.length == 0){
return ;
}
// 记录行中出现的重复
boolean row [][] = new boolean[9][10];
// 记录列中出现的重复
boolean col [][] = new boolean[9][10];
// 记录九宫格中出现的重复
boolean block[][] = new boolean[9][10];
for (int i = 0; i < block.length; i++) {
for (int j = 0; j < block.length; j++) {
if(board[i][j] != '.'){
int num = (int)(board[i][j] - '0');
row[i][num] = true;
col[j][num] = true;
block[3 * (i / 3) + j / 3][num] = true;
}
}
}
get(board, row, col, block);
}
public boolean get(char [][]board,boolean row[][],boolean col[][],boolean block[][]){
// 首先寻找最前面的'.'
int x = 0;
int y = 0;
while (board[x][y] != '.') {
if(y + 1 == 9){
x ++;
if(x == 9){
return true ;
}
y = 0;
}else {
y++;
}
}
// 到这里就找到了最先的点x,y尝试放入1-9
for (char c = '1'; c <= '9';c++) {
if(testVaild(block, row, col, x, y, c)){
board[x][y] = c;
row[x][c - '0'] = true;
col [y][c - '0'] = true;
block[3 *(x / 3) + y / 3][c - '0'] = true;
if(!get(board, row, col, block)){
board[x][y] = '.';
row[x][c - '0'] = false;
col [y][c - '0'] = false;
block[3 *(x / 3) + y / 3][c - '0'] = false;
}else {
return true;
}
}
}
return false;
}
public boolean testVaild(boolean block[][],boolean row[][]
,boolean col[][],int x,int y,char c){
if(row[x][c - '0'] || col[y][c - '0'] || block [3 *(x / 3) + y / 3][c - '0'] ){
return false;
}
return true;
}
}```