LeetCode 51. N 皇后
题目链接:51. N 皇后
思路:回溯经典题,是那种没吃过猪肉也肯定听说过的知名题。其实这道题思路不复杂(相比其他经典的hard题例如接水雨来说),作为困难题主要难在逻辑判断的复杂性、对复杂情况和用例的处理上,此题主要难在皇后是否被攻击的逻辑判断上。还有一些变量的小细节在下方代码中有所注释。
Python版本:
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
res = []
chess = [["."]*n for _ in range(n)]
def backtrack(row):
if row==n:
tmp = []
for path in chess:
cur_path = "".join(path)
tmp.append(cur_path)
res.append(tmp)
# 遍历所在行的每一列
for i in range(n):
if self.isValid(n, row, i, chess):
chess[row][i] = "Q"
backtrack(row+1) # 此处递归的是下一行, 所以是row+1, 而不是i+1
chess[row][i] = "."
backtrack(0)
return res
def isValid(self, n, row, col, chess):
# 判断当前列之上是否已经有皇后
for i in range(row):
if chess[i][col] == "Q":
return False
# 判断左斜上方是否已经有皇后
i = row-1
j = col-1
while i>=0 and j>=0:
if chess[i][j] == "Q":
return False
i -= 1
j -= 1
# 判断右斜上方是否已经有皇后
i = row-1
j = col+1
while i>=0 and j<n:
if chess[i][j] == "Q":
return False
i -= 1
j += 1
return True
go版本:
func solveNQueens(n int) [][]string {
var res [][]string
chess := make([][]string, n)
for i:= 0; i < n; i++ {
chess[i] = make([]string, n)
}
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
chess[i][j] = "."
}
}
var backtrack func(int)
backtrack = func(row int) {
if row==n {
tmp := make([]string, n)
for i, v := range chess {
tmp[i] = strings.Join(v, "")
}
res = append(res, tmp)
}
for i:=0; i<n; i++ {
if isValid(n, row, i, chess) {
chess[row][i] = "Q"
backtrack(row + 1)
chess[row][i] = "."
}
}
}
backtrack(0)
return res
}
func isValid(n, row, col int, chess [][]string) bool {
for i := 0; i < row; i++ {
if chess[i][col] == "Q" {
return false
}
}
for i, j := row-1, col-1; i >= 0 && j >= 0; i, j = i-1, j-1 {
if chess[i][j] == "Q" {
return false
}
}
for i, j := row-1, col+1; i >= 0 && j < n; i, j = i-1, j+1 {
if chess[i][j] == "Q" {
return false
}
}
return true
}