LeetCode 36 Valid Sudoku 数独子问题 子矩阵判别法

Valid Sudoku

Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.


A partially filled sudoku which is valid.

Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

解题思路:本题即为判断是否满足数独的三个条件,每一行每一列以及每个3X3粗线宫中没有1-9的重复元素。

这个题的难度在leetcode里面是easy,也就是说,稍有常识的人都会想到一个算法,暴力法,通过遍历完成。我开始也这么想,但并没有这么做,经过仔细思考并看了其他大神的做法,学到了一个O(n^2)的算法,行列宫的判断算法。这里的行和列都比较容易,就是判断每行的对应元素是否重复。而宫的判断比较复杂,要求利用现有的行和列下标判断出属于对应的子矩阵。对于一个3X3的子矩阵来说,有如下二元函数满足判断条件,T=i-i%3+j/3.该函数可以推广到任意大小的子矩阵。上述T则对应子矩阵的序号。这个做法实在是太精妙了,但是我想不出这个二元函数的正确性的证明。。。

代码如下:

 public boolean isValidSudoku(char[][] board) {
		 //每一行每一列每一宫都有数字且不重复 由此设置三个数组来判断
		 boolean [][]row = new boolean[9][9];
		 boolean [][]col = new boolean[9][9];
		 boolean [][]block = new boolean[9][9];
		 for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				if(board[i][j]=='.')continue;
			    int num = board[i][j]-'1';//charToInt
			    if(row[num][i]||col[num][j]||block[num][i-i%3+j/3]){
			    	return false;
			    }
			    //表示出现过
			    row[num][i]=col[num][j]=block[num][i-i%3+j/3]=true;
			}
		}
	        return true;
	    }	

参考文章:http://blog.csdn.net/doc_sgl/article/details/13002461

你可能感兴趣的:(LeetCode 36 Valid Sudoku 数独子问题 子矩阵判别法)