【困难】力扣算法题解析LeetCode52:N皇后 II

关注文末的名片达文汐,回复关键词“力扣源码”,即可获取完整源码!!详见:源码和核心代码的区别

题目详情

n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击(皇后可以攻击同一行、同一列、同一对角线上的其他皇后)。
给定一个整数 n,返回 n 皇后问题不同的解决方案的数量。

示例 1:
在这里插入图片描述
输入:n = 4
输出:2
解释:4 皇后问题存在两个不同的解法。

示例 2:
输入:n = 1
输出:1

提示:

  • 1 <= n <= 9

解题思路

核心思路: 使用深度优先搜索(DFS)与位运算优化,逐行放置皇后,并通过三个整数记录列、主对角线和副对角线的占用状态,避免冲突。

  1. 状态表示:

    • cols:整数的二进制位表示列的占用情况(第 i 位为 1 表示第 i 列已被占用)。
    • diag1:整数的二进制位表示主对角线(左上到右下)的占用情况。主对角线索引为 row - col + n - 1(确保非负)。
    • diag2:整数的二进制位表示副对角线(右上到左下)的占用情况。副对角线索引为 row + col
  2. 递归放置皇后:

    • 从第 0 行开始,逐行放置皇后。
    • 对当前行的每一列进行尝试:
      • 检查列、主对角线、副对角线是否冲突(通过位运算快速判断)。
      • 若无冲突,更新状态(设置对应位为 1),递归处理下一行。
    • 递归终止:当行数 row == n 时,表示找到一种解法,计数加 1
  3. 位运算优化:

    • 冲突检测:通过 & 运算检查目标位是否为 1
    • 状态更新:通过 | 运算设置新状态,并作为参数传递到下一层递归,避免显式回溯。

优点:

  • 时间优化:位运算实现快速冲突检测,时间复杂度为 O(n!)。
  • 空间优化:仅用三个整数记录状态,空间复杂度为 O(1)。

代码实现(Java)

class Solution {
    public int totalNQueens(int n) {
        return dfs(0, n, 0, 0, 0);
    }
    
    private int dfs(int row, int n, int cols, int diag1, int diag2) {
        if (row == n) {
            return 1; // 所有行放置完成,找到一种解法
        }
        int count = 0;
        for (int col = 0; col < n; col++) {
            // 计算主对角线和副对角线的索引
            int d1 = row - col + n - 1; // 主对角线索引(确保非负)
            int d2 = row + col;         // 副对角线索引
            
            // 检查列、主对角线、副对角线是否冲突
            if ((cols & (1 << col)) != 0) continue;   // 列冲突
            if ((diag1 & (1 << d1)) != 0) continue;   // 主对角线冲突
            if ((diag2 & (1 << d2)) != 0) continue;   // 副对角线冲突
            
            // 递归下一行,更新状态(设置对应位为1)
            count += dfs(row + 1, n, 
                         cols | (1 << col), 
                         diag1 | (1 << d1), 
                         diag2 | (1 << d2));
        }
        return count;
    }
}

代码说明

  1. 递归函数 dfs 参数:

    • row:当前处理的行。
    • n:棋盘大小。
    • cols:列占用状态(二进制位表示)。
    • diag1:主对角线占用状态。
    • diag2:副对角线占用状态。
  2. 关键操作:

    • 冲突检测:使用 (state & (1 << index)) != 0 检测目标位是否被占用。
    • 状态更新:通过 state | (1 << index) 设置新状态,并传递至下一层递归。
    • 递归终止:当 row == n 时,返回 1 表示找到一种解法。
  3. 返回值:

    • 递归过程中累加所有可行解的数量。

提交详情(执行用时、内存消耗)

在这里插入图片描述

我的名片👇👇👇👇👇👇👇👇👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值