链接
题目.
难度:
high
解答:
用普通的深度优先搜索可以达到目标,但是不是最优解。这题的难点就在于发现对角线的i+j或者i-j是常数,于是可以用一组变量表示。
package main
import (
"fmt"
)
func searchSolution(n, curRow int, colMark, slashMark, backSlashMark []int, solutions *int) {
for j := 0; j < n; j++ {
if colMark[j] > 0 {
continue
}
if slashMark[curRow+j] > 0 {
continue
}
if backSlashMark[curRow-j+n] > 0 {
continue
}
if curRow == (n - 1) {
*solutions++
return
}
//test curRow, j
colMark[j]++
slashMark[curRow+j]++
backSlashMark[curRow-j+n]++
searchSolution(n, curRow+1, colMark, slashMark, backSlashMark, solutions)
colMark[j]--
slashMark[curRow+j]--
backSlashMark[curRow-j+n]--
}
}
func totalNQueens(n int) int {
if n == 1 {
return 1
}
if n <= 3 {
return 0
}
//rowMark := make([]int, n) // const i
colMark := make([]int, n) // const j
slashMark := make([]int, 2*n) // const i+j: 0 ~ 2*(n-1)
backSlashMark := make([]int, 2*n) // const i-j: -(n-1) ~ (n-1), i-j+n: 1 ~ (2*n -1)
solutions := 0
searchSolution(n, 0, colMark, slashMark, backSlashMark, &solutions)
return solutions
}
func main() {
fmt.Println(totalNQueens(4))
}
复杂度分析
time
O(n!)
space
O(n)
执行结果
执行用时 :0 ms, 在所有 golang 提交中击败了100.00%的用户
内存消耗 :1.8, 在所有 golang 提交中击败了80.的用户