LeetCode 36. Valid Sudoku 验证数独

266 阅读2分钟

leetcode.com/problems/va…

Discuss:www.cnblogs.com/grandyang/p…

Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:

  1. Each row must contain the digits 1-9 without repetition.
  2. Each column must contain the digits 1-9 without repetition.
  3. Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-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:

image.png

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 1-9 or '.'.

解法一:

这道题让验证一个方阵是否为数独矩阵,想必数独游戏我们都玩过,就是给一个 9x9 大小的矩阵,可以分为 9 个 3x3 大小的矩阵,要求是每个小矩阵内必须都是 1 到 9 的数字不能有重复,同时大矩阵的横纵列也不能有重复数字,是一种很经典的益智类游戏,经常在飞机上看见有人拿着纸笔在填数,感觉是消磨时光的利器。这道题给了一个残缺的二维数组,让我们判断当前的这个数独数组是否合法,即要满足上述的条件。判断标准是看各行各列是否有重复数字,以及每个小的 3x3 的小方阵里面是否有重复数字,如果都无重复,则当前矩阵是数独矩阵,但不代表待数独矩阵有解,只是单纯的判断当前未填完的矩阵是否是数独矩阵。那么根据数独矩阵的定义,在遍历每个数字的时候,就看看包含当前位置的行和列以及 3x3 小方阵中是否已经出现该数字,这里需要三个 boolean 型矩阵,大小跟原数组相同,分别记录各行,各列,各小方阵是否出现某个数字,其中行和列标志下标很好对应,就是小方阵的下标需要稍稍转换一下,具体代码如下:

class Solution {
    fun isValidSudoku(board: Array<CharArray>): Boolean {
        if (board.isEmpty()) {
            return false
        }
        val rows = Array(9) { BooleanArray(board.size) }
        val cols = Array(9) { BooleanArray(board.size) }
        val blocks = Array(9) { BooleanArray(board.size) }

        for (i in board.indices) {
            for (j in board[0].indices) {
                val digit = board[i][j]
                if (digit == '.') {
                    continue
                }
                val c = digit - '1'
                if (rows[i][c] || cols[c][j] || blocks[3 * (i / 3) + j / 3][c]) {
                    return false
                }
                rows[i][c] = true
                cols[c][j] = true
                blocks[3 * (i / 3) + j / 3][c] = true
            }
        }
        return true
    }
}