leetcode:sudoku solver

sudoku solver,题意如下:

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.


A sudoku puzzle...


...and its solution numbers marked in red.

也就是解普通的数独,开始想到了很naive的模拟方法,从只有一种可能性也就是可以确定的数字开始填充,结果当然是跑不出来的,因为有些地方是不止一种解的,因为这道题在回溯法的分类里,就重新想了一下。

既然有多种解,那就只能一个个可能的试过去,试到一种解就可以输出了。

具体的用可以理解的话来说,过程是这样的:

遍历整个数独表格,一旦碰到一个空位,就往里填个1,然后判断这个1是否在所在的行和列和小的九宫格里是可行的,如果可行,就往下遍历,如果不可行,就填2,重复上面的操作,一直试到9为止。

先贴上代码:

public static void solveSudoku(char[][] board) {
		sudoku(board);
    }
	
	 static boolean sudoku(char[][] board){
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				if(board[i][j] == '.'){
					for(int k=1;k<=9;k++){
						board[i][j] = (char)('0'+k);
						if(isValid(board, i, j) && sudoku(board)){
							return true;
						}
						board[i][j] = '.';
					}
					return false;
				}
			}
		}
		return true;
	}
	
	 static boolean isValid(char[][] board,int i,int j){
		for(int a=0;a<9;a++){
			if(board[i][j] == board[i][a] && a!=j)return false;
			if(board[i][j] == board[a][j] && a!=i)return false;
		}
		for(int a=3*(i/3);a<3*(i/3+1);a++){
			for(int b=3*(j/3);b<3*(j/3+1);b++){
				if(a!=i && b!=j && board[a][b] == board[i][j]){
					return false;
				}
			}
		}
		return true;
	}
	
	public static void main(String[] args) {
		char[][] a = {{'.','.','9','7','4','8','.','.','.'},
				      {'7','.','.','.','.','.','.','.','.'},
				      {'.','2','.','1','.','9','.','.','.'},
				      {'.','.','7','.','.','.','2','4','.'},
				      {'.','6','4','.','1','.','5','9','.'},
				      {'.','9','8','.','.','.','3','.','.'},
				      {'.','.','.','8','.','3','.','2','.'},
				      {'.','.','.','.','.','.','.','.','6'},
				      {'.','.','.','2','7','5','9','.','.'}};
		solveSudoku(a);
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				System.out.print(a[i][j]+" ");
			}
			System.out.println();
		}
	}
代码中的奥妙,只能意会了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值