51. N - Queens
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[“.Q..”, // Solution 1
“…Q”,
“Q…”,
“..Q.”],
[“..Q.”, // Solution 2
Q…”,
“…Q”,
“.Q..”]
]
题意:
n皇后难题的问题是将n个皇后放在在n×n棋盘,没有任何两个皇后互相攻击。给定一个整数n,返回所有不同的解决n皇后问题的解。每个解决方案包含一个独特的N皇后的位置板配置,分别用“Q”和“.”都表明一个皇后和一个空的空间。
思路:
求解N皇后问题是算法中回溯法应用的一个经典案例, 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。
在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满足某种要求的可能或最优的情况,从而得到整个问题的解。回溯算法就是解决这种问题的“通用算法”,有“万能算法”之称。N皇后问题在N增大时就是这样一个解空间很大的问题,所以比较适合用这种方法求解。这也是N皇后问题的传统解法。
1 | 下面是算法的高级伪码描述,这里用一个N*N的矩阵来存储棋盘: |
1 | //下面要解决的是使用何种方法来找到所有的N皇后的解。上面说过该问题是回溯法的经典应用,所以可以使用回溯法来解决该问题,具体实现也有两个途径,递归和非递归。递归方法较为简单,大致思想如下: |
方法一:
递归实现,主要思路如上述思路所述。
1 | /**************************************************************************************************************** |
方法二:
一般来说递归的效率比较差,下面重点讨论一下该问题的非递归实现。非递归方法的一个重要问题时何时回溯及如何回溯的问题。程序首先对N行中的每一行进行探测,寻找该行中可以放置皇后的位置,具体方法是对该行的每一列进行探测,看是否可以放置皇后,如果可以,则在该列放置一个皇后,然后继续探测下一行的皇后位置。如果已经探测完所有的列都没有找到可以放置皇后的列,此时就应该回溯,把上一行皇后的位置往后移一列,如果上一行皇后移动后也找不到位置,则继续回溯直至某一行找到皇后的位置或回溯到第一行,如果第一行皇后也无法找到可以放置皇后的位置,则说明已经找到所有的解程序终止。如果该行已经是最后一行,则探测完该行后,如果找到放置皇后的位置,则说明找到一个结果,打印出来。但是此时并不能再此处结束程序,因为我们要找的是所有N皇后问题所有的解,此时应该清除该行的皇后,从当前放置皇后列数的下一列继续探测。
1 | /**************************************************************************************************************** |
方法三:
递归实现,主要思路如上述思路所述,但是此方法是利用位运算之间的关系来判断皇后放的位置,效率高(但是自己也不太理解)。
1 | /*************************************************************************************************************** |
Java Code
1 | class Solution { |