Lever's Castle

36. 有效的数独

June 22, 2020

https://leetcode-cn.com/problems/valid-sudoku/

使用语言 Go

func isValidSudoku(board [][]byte) bool {
    suduLen := 9
    byteIndexes := make(map[byte]map[int]int)
    for i := 0; i < len(board); i++ {
        for j := 0; j < len(board[i]); j++ {
            if string(board[i][j]) == "." {
                continue
            }
            if bm, ok := byteIndexes[board[i][j]]; ok {
                // 先检查横竖
                if _, ok := bm[i]; ok {
                    return false
                } else if _, ok := bm[j + suduLen]; ok {
                    return false
                }
                // 再检查九宫格
                for x, y := range bm {
                    if x >= suduLen {
                        x, y = y, x - suduLen
                    }
                    if getCellNum(x, y) == getCellNum(i, j) {
                        return false
                    }
                }
                bm[i] = j
                bm[j+suduLen] = i
            } else {
                byteIndexes[board[i][j]] = make(map[int]int)
                byteIndexes[board[i][j]][i] = j
                byteIndexes[board[i][j]][j+suduLen] = i
            }
        }
    }

    return true
}

// 0, 1, 2
// 3, 4, 5
// 6, 7, 8
func getCellNum(x, y int) int {
    if x < 3 {
        if y < 3 {
            return 0
        } else if y < 6 {
            return 3
        } else {
            return 6
        }
    } else if x < 6 {
        if y < 3 {
            return 1
        } else if y < 6 {
            return 4
        } else {
            return 7
        }
    } else {
        if y < 3 {
            return 2
        } else if y < 6 {
            return 5
        } else {
            return 8
        }
    }
}

题解:

其实解题思路挺简单,想清楚怎么检查每个元素是否合法即可。对于数独来讲,横竖每个数字只能出现一次,每个 3x3 九宫格只能出现一次。我直接定义了一个 map 用来记录数独中每个数字出现的位置的坐标,这样横竖重复的情况很容易就能找到。至于九宫格内的位置,我通过遍历已有的位置来看是否在同一个 3x3 九宫格内。


Lever

痕迹
没有过去,就没法认定现在的自己