leetcode题解之52. N皇后 II n 皇后问题研究的是如何将

leetcode题解之52. N皇后 IIn 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。上图为 8 皇后问题的一种解法。给定一个整数 n,返回 n 皇后不同的解决方案的数量。示例:输入: 4输出: 2解释: 4 皇后问题存在如下两个不同的解法。[[".Q…", // 解法 1“…Q”,“Q…”,“…Q.”],["…Q.", // 解法 2“Q…”,“…Q”,“.Q…”]]提示:皇后,是国际象棋中的棋子,意味着国王的妻
摘要由CSDN通过智能技术生成

leetcode题解之52. N皇后 II
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

示例:

输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],

["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]

提示:

皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一或七步,可进可退。(引用自 百度百科 - 皇后 )
直观想法
这个问题是一个经典的问题,感受解法的优雅性很重要。

第一个想法是使用蛮力法,意味着生成在棋盘上放置 N 个皇后的所有可能的情况,并且检查是否保证没有皇后可以互相攻击。这意味着 \mathcal{O}(N^N)O(NN) 的时间复杂度,因此我们必须考虑优化。

下面是两个有用的编程概念。

第一个叫做 约束编程.

它的基本含义是在放置每个皇后以后增加限制。当在棋盘上放置了一个皇后后,立即排除当前行,列和对应的两个对角线。该过程传递了 约束 从而有助于减少需要考虑情况数。

51_pic.png

第二个叫做 回溯法.

我们来想象一下,当在棋盘上放置了几个皇后且不会相互攻击。但是选择的方案不是最优的,因为无法放置下一个皇后。此时我们该怎么做?回溯。意思是回退一步,来改变最后放置皇后的位置并且接着往下放置。如果还是不行,再 回溯。

51_backtracking_.png

方法1:回溯
在建立算法之前,我们来考虑两个有用的细节。

一行只可能有一个皇后且一列也只可能有一个皇后。

这意味着没有必要再棋盘上考虑所有的方格。只需要按列循环即可。

对于所有的主对角线有 行号 + 列号 = 常数,对于所有的次对角线有 行号 - 列号 = 常数.

这可以让我们标记已经在攻击范围下的对角线并且检查一个方格 (行号, 列号) 是否处在攻击位置。

51_diagonals.png

现在已经可以写回溯函数 backtrack(row = 0).

从第一个 row = 0 开始.

循环列并且试图在每个 column 中放置皇后.

如果方格 (row, column) 不在攻击范围内

在 (row, column) 方格上放置皇后。
排除对应行,列和两个对角线的位置。
If 所有的行被考虑过,row == N
意味着我们找到了一个解
Else
继续考虑接下来的皇后放置 backtrack(row + 1).
回溯:将在 (row, column) 方格的皇后移除.
下面是上述算法的一个直接的实现。

1 / 34
Java
Python

class Solution {
public boolean is_not_under_attack(int row, int col, int n,
int [] rows,
int [] hills,
int [] dales) {
int res = rows[col] + hills[row - col + 2 * n] + dales[row + col];
return (res == 0) ? true : false;
}
public int backtrack(int row, int count, int n,

int [] rows,

int [] hills,

int [] dales) {

for (int col = 0; col < n; col++) {

if (is_not_under_attack(row, col, n, rows, hills, dales)) {

// place_queen

rows[col] = 1;

hills[row - col + 2 * n] = 1; // “hill” diagonals

dales[row + col] = 1; //“dale” diagonals

<span class="hljs-comment">// if n queens are already placed</span>
<span class="hljs-keyword">if</span&
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值