[LeetCode] #36 有效的数独
请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
输入:board =
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true
使用哈希表
class Solution { public boolean isValidSudoku(char[][] board) { Set<Character> set1 = new HashSet<>(); Set<Character> set2 = new HashSet<>(); Set<Character> set3 = new HashSet<>(); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[j][i] != '.' && !set1.add(board[j][i])) return false; if (board[i][j] != '.' && !set2.add(board[i][j])) return false; //(0,0)(0,1)(0,2)(1,0)(1,1)(1,2)(2,0)(2,1)(2,2) //(0,3)(0,4)(0,5)(1,3)(1,4)(1,5)(2,3)(2,4)(2,5) //(0,6)(0,7)(0,8)(1,6)(1,7)(1,8)(2,6)(2,7)(2,8) //(3,0)(3,1)(3,2)(4,0)(4,1)(4,2)(5,0)(5,1)(5,2) //(3,3)(3,4)(3,5)(4,3)(4,4)(4,5)(5,3)(5,4)(5,5) //(3,6)(3,7)(3,8)(4,6)(4,7)(4,8)(5,6)(5,7)(5,8) //(6,0)(6,1)(6,2)(7,0)(7,1)(7,2)(8,0)(8,1)(8,2) //(6,3)(6,4)(6,5)(7,3)(7,4)(7,5)(8,3)(8,4)(8,5) //(6,6)(6,7)(6,8)(7,6)(7,7)(7,8)(8,6)(8,7)(8,8) if (board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3] != '.' && !set3.add(board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3])) return false; } set1.clear(); set2.clear(); set3.clear(); } return true; } }
使用数组代替哈希表
class Solution { public boolean isValidSudoku(char[][] board) { int[][] rows = new int[9][9]; int[][] columns = new int[9][9]; int[][][] subboxes = new int[3][3][9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { char c = board[i][j]; if (c != '.') { int index = c - '0' - 1; rows[i][index]++; columns[j][index]++; subboxes[i / 3][j / 3][index]++; if (rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i / 3][j / 3][index] > 1) { return false; } } } } return true; } }
或者
class Solution { 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] != '.') { int num = board[i][j] - '1'; int blockIndex = i / 3 * 3 + j / 3; if (row[i][num] || col[j][num] || block[blockIndex][num]) { return false; } else { row[i][num] = true; col[j][num] = true; block[blockIndex][num] = true; } } } } return true; } }
使用位运算代替哈希表
class Solution { public boolean isValidSudoku(char[][] board) { for (int i = 0; i < 9; i++) { int tmp = 0; int tmp2 = 0; for (int j = 0; j < 9; j++) { if (board[i][j] != '.') { int t = tmp | (1 << (board[i][j] - '0')); if (t == tmp) return false; tmp = t; } if (board[j][i] != '.') { int t = tmp2 | (1 << (board[j][i] - '0')); if (t == tmp2) return false; tmp2 = t; } } } for (int x = 0; x <= 6; x+=3) { for (int y = 0; y <= 6; y+=3) { int tmp = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i + x][j + y] != '.') { int t = tmp | (1 << (board[i + x][j + y] - '0')); if (t == tmp) return false; tmp = t; } } } } } return true; } }
知识点:无
总结:无