N皇后
问题描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
回溯解法O(N^N)
复杂度分析
时间复杂度:O(N!). 放置第 1 个皇后有 N 种可能的方法,放置两个皇后的方法不超过 N (N - 2) ,放置 3 个皇后的方法不超过 N(N - 2)(N - 4) ,以此类推。总体上,时间复杂度为O(N!) .
#
# @lc app=leetcode.cn id=51 lang=python3
#
# [51] N皇后
#
# @lc code=start
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
# 判断是否可以放置:
# 1、因为是按行递归,所以行肯定不相等;
# 2、判断当前列j是否会与前i-1个放置好的皇后在相同列上
# 3、判断当前行i和列j,是否与前i-1个放置好的皇后在相同斜线上
def isValiable(record, i, j):
for x in range(i):
if record[x] == j or abs(i - x) == abs(record[x] - j):
return False
return True
def processN(i, n, record, result):
if i == n:
# i==n说明所有皇后已经放置好,遍历record构成棋盘放入result
lis = []
for x in range(n):
s = ""
for y in range(n):
s += "." if record[x] != y else "Q"
lis.append(s)
result.append(lis)
return
for j in range(n):
if isValiable(record, i ,j):
record[i] = j
processN(i+1, n, record, result)
return
record = [-1] * n
result = []
processN(0, n, record, result)
return result
# @lc code=end
优化回溯解法:
基本规程与上面的一致,但使用位运算来进行加速。(使用Java要注意变量的最高位数,例如int类型的最高只有32位)