返回
算法之美:解码 Leetcode N-Queens 难题
见解分享
2023-10-30 12:53:16
前言
Leetcode 上的 N-Queens 难题可谓是算法领域的经典之作。它要求你在 NxN 的棋盘上摆放 N 个皇后,使其互不攻击。乍看之下,这似乎是一项艰巨的任务,但本文将带你深入理解该难题,并揭秘其背后的巧妙解法和优化技巧,让你在算法竞赛或面试中脱颖而出。
算法思路
破解 N-Queens 难题的关键在于逐行放置皇后。我们使用三个 32 位二进制整数来分别记录当前行、左对角线和右对角线上不能放置皇后的位置。当我们遍历当前行时,如果当前位置在三个整数中都为 0,则表示该位置可以放置皇后;否则,我们跳过该位置。
优化技巧
为了进一步优化算法,我们利用这样一个事实:垂直翻转 8 皇后解中的任意一个解都可以得到一个新的解。因此,我们仅需计算一半的解,从而大幅缩短了求解时间。
Python 实现
def solve_n_queens(n):
# 初始化
board = [[0] * n for _ in range(n)]
columns = 0
left_diagonals = 0
right_diagonals = 0
# 逐行放置皇后
def backtrack(row):
if row == n:
return 1 # 一个解找到
# 遍历当前行
count = 0
for col in range(n):
if ((1 << col) & columns == 0 and
(1 << (row + col)) & left_diagonals == 0 and
(1 << (n - 1 - row + col)) & right_diagonals == 0):
# 当前位置合法
board[row][col] = 1
columns |= 1 << col
left_diagonals |= 1 << (row + col)
right_diagonals |= 1 << (n - 1 - row + col)
count += backtrack(row + 1)
# 回溯
board[row][col] = 0
columns ^= 1 << col
left_diagonals ^= 1 << (row + col)
right_diagonals ^= 1 << (n - 1 - row + col)
return count
return backtrack(0)
示例代码
n = 8
result = solve_n_queens(n)
print(result) # 输出:92
结论
N-Queens 难题不仅考察了算法能力,也考验了优化技巧的运用。通过逐行放置皇后,并巧妙地利用二进制位图和对称性优化,我们可以高效地求解该难题。熟练掌握这些技巧将大大提升你解决算法问题的能力,在面试或编程竞赛中占据优势。