1. 题目描述

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

示例 1:

  1. 输入:
  2. [
  3. ["5","3",".",".","7",".",".",".","."],
  4. ["6",".",".","1","9","5",".",".","."],
  5. [".","9","8",".",".",".",".","6","."],
  6. ["8",".",".",".","6",".",".",".","3"],
  7. ["4",".",".","8",".","3",".",".","1"],
  8. ["7",".",".",".","2",".",".",".","6"],
  9. [".","6",".",".",".",".","2","8","."],
  10. [".",".",".","4","1","9",".",".","5"],
  11. [".",".",".",".","8",".",".","7","9"]
  12. ]
  13. 输出: true

示例 2:

  1. 输入:
  2. [
  3. ["8","3",".",".","7",".",".",".","."],
  4. ["6",".",".","1","9","5",".",".","."],
  5. [".","9","8",".",".",".",".","6","."],
  6. ["8",".",".",".","6",".",".",".","3"],
  7. ["4",".",".","8",".","3",".",".","1"],
  8. ["7",".",".",".","2",".",".",".","6"],
  9. [".","6",".",".",".",".","2","8","."],
  10. [".",".",".","4","1","9",".",".","5"],
  11. [".",".",".",".","8",".",".","7","9"]
  12. ]
  13. 输出: false
  14. 解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
  15. 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 给定数独序列只包含数字 1-9 和字符 ‘.’ 。
  • 给定数独永远是 9x9 形式的。

    2. 解题思路

    这个题目中,我们可以使用map来存贮已经遍历的过得值,如果map已经存在就说明不符合要求,不存在就将当前的值存入map,继续遍历。

首先,先对整个表格行和进行验证,最后在对九个小方格进行验证。需要注意的是,在对整个表格验证时,每次遍历完一行和一列,都要对map进行清空,在对九个小方格进行验证时,每遍历完一个小方格就需要对map进行清空。

这里我们用到了map数据结构的clear()方法、has()方法、set()方法,分别用来清空map,判断map中是否存在某值,在map中设置某值。

3. 代码实现

  1. /**
  2. * @param {character[][]} board
  3. * @return {boolean}
  4. */
  5. var isValidSudoku = function(board) {
  6. // 验证整个宫格的行和列
  7. const mapRow = new Map(), mapCol = new Map()
  8. for(let i = 0; i < 9; i++){
  9. mapRow.clear()
  10. mapCol.clear()
  11. for(let j = 0; j < 9; j++){
  12. if(mapRow.has(board[i][j])) return false
  13. if(mapCol.has(board[j][i])) return false
  14. if(board[i][j] !== "."){
  15. mapRow.set(board[i][j], j)
  16. }
  17. if(board[j][i] !== "."){
  18. mapCol.set(board[j][i], i)
  19. }
  20. }
  21. }
  22. // 分别验证九个小个方格
  23. const map = new Map()
  24. let m = 0, n = 0
  25. while(m < 9){
  26. while(n < 9){
  27. map.clear()
  28. for(let i = m; i < m + 3; i++){
  29. for(let j = n; j < n + 3; j++){
  30. if(map.has(board[i][j])) return false
  31. if(board[i][j] !== "."){
  32. map.set(board[i][j], j)
  33. }
  34. }
  35. }
  36. n += 3
  37. }
  38. m += 3
  39. n = 0
  40. }
  41. return true
  42. };

4. 提交结果

36. 有效的数独 - 图1