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

来源:互联网 发布:如何自学英语 知乎 编辑:程序博客网 时间:2024/04/28 00:45

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
0 0