Leetcode1-100: 36. Valid Sudoku
问题描述
题目要求: 输入一个代表数独的字符型二维数组,里面元素是’.'说明没有填上,判断这个数组代表的数独是否是合法状态。
解题思路
implement 1
使用一个字符型hashSet,每次遇到一个非`'.'`元素c就存储一个字符串格式为:
C + in Line + lineNo. + in Column + colNo. + in Stack [line/3] [col/3]
这样存储的好处是只需要用一个HashSet就可以,不然需要三个分别存储行,列和box(每个box为一个3 * 3的小方块)信息。这样存储之后,每次遇到一个待检查元素之后,只需要判断对应的字符串是否存在于HashSet即可。
implement 2
比较常规的一个解法,直接每次取得一个待验证的字符之后,判断与其相关的验证信息是否成立即可。即:
1. 所在行是否存在相同元素
2. 所在列是否存在相同元素
3. 所在的box是否存在相同的元素。
代码实现
implement 1 HashSet法
public boolean isValidSudoku(char[][] board) {
Set<String> hash = new HashSet<>();
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
if(board[i][j] != '.') {
String lineCheck = String.valueOf(board[i][j])+" in Line "+String.valueOf(i) ;
String columnCheck = String.valueOf(board[i][j]) +" in Column "+String.valueOf(j);
String stackCheck = String.valueOf(board[i][j]) + " in Part "+String.valueOf(i/3)+" "+String.valueOf(j/3);
if(hash.contains(lineCheck)||hash.contains(columnCheck)||hash.contains(stackCheck))
return false;
else {
hash.add(lineCheck);
hash.add(columnCheck);
hash.add(stackCheck);
}
}
}
}
return true;
}
复杂度分析:
外层的两个循环说明循环一共执行了n2次,循环本身由于HashSet的操作使得每次的查询时O(1),所以时间复杂度是O(n2),但是由于建立HashSet本身和字符串建立本身的时间复杂度比较高,所以对于9*9的输入矩阵来说实际操作的时间还是很大的
时间复杂度:O(n2)
空间复杂度:O(n2)
implement 2 Brute Force法
public boolean isValidSudoku(char[][] board) {
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
if(board[i][j] != '.') {
char c = board[i][j];
board[i][j] = '.';
if(!passCheck(board, i, j, c))
return false;
board[i][j] = c;
}
}
}
return true;
}
public boolean passCheck(char[][] board, int line, int col, char c) {
for(int i = 0; i < board.length; i++) {
if(board[i][col] == c || board[line][i] == c)
return false;
}
for(int i = line/3 * 3; i<line/3*3+3; i++) {
for(int j = col/3 * 3; j < col/3*3 + 3; j++) {
if(board[i][j] == c)
return false;
}
}
return true;
}
复杂度分析:
外层的两个循环说明循环一共执行了n2次,循环本身需要检测所在行或列的所有元素,所以时间复杂度是O(n3)
时间复杂度:O(n3)
空间复杂度:O(1)