59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
package top100liked
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// https://leetcode.cn/problems/n-queens/description/?envType=study-plan-v2&envId=top-100-liked
|
|
|
|
func solveNQueens(n int) [][]string {
|
|
res := [][]string{}
|
|
path := []string{}
|
|
// 同列/同对角线共享一个不变量,用三个独立数组各标记一条线是否被占。
|
|
// 列:col;主对角线(↘):row-col 为常数,+n-1 偏移成非负下标;
|
|
// 副对角线(↙):row+col 为常数,本身非负。行约束不需要(每行只放一个)。
|
|
cols := make([]bool, n) // cols[col]:第 col 列是否被占
|
|
diag1 := make([]bool, 2*n-1) // diag1[row-col+n-1]:↘ 对角线是否被占
|
|
diag2 := make([]bool, 2*n-1) // diag2[row+col]:↙ 对角线是否被占
|
|
|
|
var helper func()
|
|
helper = func() {
|
|
row := len(path)
|
|
if row == n {
|
|
cp := make([]string, len(path))
|
|
copy(cp, path)
|
|
res = append(res, cp)
|
|
return
|
|
}
|
|
for col := range n {
|
|
d1 := row - col + n - 1 // ↘ 对角线下标
|
|
d2 := row + col // ↙ 对角线下标
|
|
if !cols[col] && !diag1[d1] && !diag2[d2] {
|
|
path = append(path, strings.Repeat(".", col)+"Q"+strings.Repeat(".", n-col-1))
|
|
cols[col] = true
|
|
diag1[d1] = true
|
|
diag2[d2] = true
|
|
helper()
|
|
cols[col] = false
|
|
diag1[d1] = false
|
|
diag2[d2] = false
|
|
path = path[:len(path)-1]
|
|
}
|
|
}
|
|
}
|
|
|
|
helper()
|
|
|
|
return res
|
|
}
|
|
|
|
func Test(t *testing.T) {
|
|
fmt.Printf("%+v\n", solveNQueens(4))
|
|
}
|
|
|
|
func Test2(t *testing.T) {
|
|
fmt.Printf("%+v\n", solveNQueens(1))
|
|
}
|