返回

算法之美:解码 Leetcode N-Queens 难题

见解分享

前言

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 难题不仅考察了算法能力,也考验了优化技巧的运用。通过逐行放置皇后,并巧妙地利用二进制位图和对称性优化,我们可以高效地求解该难题。熟练掌握这些技巧将大大提升你解决算法问题的能力,在面试或编程竞赛中占据优势。