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 九宫格内。
痕迹
没有过去,就没法认定现在的自己