8、解数独

题目描述:
编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 ‘.’ 表示。
8、解数独
8、解数独
答案被标成红色。

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;
	}
	
}```