Determine if a 9 x 9
Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
- Each row must contain the digits
1-9
without repetition. - Each column must contain the digits
1-9
without repetition. - Each of the nine
3 x 3
sub-boxes of the grid must contain the digits1-9
without repetition.
Note:
- A Sudoku board (partially filled) could be valid but is not necessarily solvable.
- Only the filled cells need to be validated according to the mentioned rules.
Example 1:
Input: 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"]] Output: true
Example 2:
Input: board = [["8","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"]] Output: false Explanation: Same as Example 1, except with the 5 in the top left corner being modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Constraints:
board.length == 9
board[i].length == 9
board[i][j]
is a digit or'.'
.
有效的数独。
题意如下
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
这个题没有什么算法可言,思路是用hashmap判断每一行,每一列,和每一个九宫格是否满足条件。如果当前的坐标内不是点(.),且当前坐标内的数字存在于hashmap则return false。判断每一行的时候,因为坐标是(i, j),所以判断(j, i)的时候可以同时判断一个对应的列是否满足题意。判断每个cube的方式是先要得到rowIndex和colIndex,这里我是当做结论一样背下来的,真的不是很好记。
- rowIndex = 3 * (i / 3)
- colIndex = 3 * (i % 3)
时间O(mn)
空间O(n)
Java实现
1 class Solution { 2 public boolean isValidSudoku(char[][] board) { 3 for (int i = 0; i < board.length; i++) { 4 HashSet<Character> rows = new HashSet<>(); 5 HashSet<Character> cols = new HashSet<>(); 6 HashSet<Character> cube = new HashSet<>(); 7 for (int j = 0; j < board[0].length; j++) { 8 if (board[i][j] != '.' && !rows.add(board[i][j])) { 9 return false; 10 } 11 if (board[j][i] != '.' && !cols.add(board[j][i])) { 12 return false; 13 } 14 int rowIndex = 3 * (i / 3); 15 int colIndex = 3 * (i % 3); 16 if (board[rowIndex + j / 3][colIndex + j % 3] != '.' 17 && !cube.add(board[rowIndex + j / 3][colIndex + j % 3])) { 18 return false; 19 } 20 } 21 } 22 return true; 23 } 24 }
JavaScript实现
1 /** 2 * @param {character[][]} board 3 * @return {boolean} 4 */ 5 var isValidSudoku = function(board) { 6 let m = board.length; 7 let n = board[0].length; 8 for (let i = 0; i < m; i++) { 9 let rows = new Set(); 10 let cols = new Set(); 11 let cubes = new Set(); 12 for (let j = 0; j < n; j++) { 13 if (board[i][j] != '.') { 14 if (!rows.has(board[i][j])) { 15 rows.add(board[i][j]); 16 } else { 17 return false; 18 } 19 } 20 if (board[j][i] != '.') { 21 if (!cols.has(board[j][i])) { 22 cols.add(board[j][i]); 23 } else { 24 return false; 25 } 26 } 27 let rowIndex = 3 * Math.floor(i / 3); 28 let colIndex = 3 * (i % 3); 29 if ( 30 board[rowIndex + Math.floor(j / 3)][colIndex + (j % 3)] != '.' 31 ) { 32 if ( 33 !cubes.has( 34 board[rowIndex + Math.floor(j / 3)][colIndex + (j % 3)] 35 ) 36 ) { 37 cubes.add( 38 board[rowIndex + Math.floor(j / 3)][colIndex + (j % 3)] 39 ); 40 } else { 41 return false; 42 } 43 } 44 } 45 } 46 return true; 47 };
2021年4月更新
我这里再推荐一个字符串的思路,来自于StefanPochmann大神。这个做法的思想是需要判断某个元素是否是 unique 的,这个思想可以运用到其他需要判断独一性的题目。这里我一时想不起来有哪些题目了,日后有总结我再加以更新。
Java实现
1 class Solution { 2 public boolean isValidSudoku(char[][] board) { 3 HashSet<String> set = new HashSet<>(); 4 for (int i = 0; i < 9; i++) { 5 for (int j = 0; j < 9; j++) { 6 if (board[i][j] != '.') { 7 String b = "(" + board[i][j] + ")"; 8 if (!set.add(b + i) || !set.add(j + b) || !set.add(i / 3 + b + j / 3)) { 9 return false; 10 } 11 } 12 } 13 } 14 return true; 15 } 16 }