八皇后问题的具体背景就不重复叙述了,下面直接给出解法。
该解法与巨著《structure and interpretation of computer program》中用Scheme代码提供的解法几乎是相同,具备函数式编程的风格。

“函数式编程的思路是自上而下的。它首先提出一个大问题,在最高层用一个函数来解决这个大问题。在这个函数内部,再用其他函数来解决小问题。再这样递归式的分解下,直到问题得到解决。”–Vamei《从Python开始学编程》

递归是解决此类问题的利器。递归的思想是找到python八皇后 回溯 python八皇后问题递归算法_函数式编程python八皇后 回溯 python八皇后问题递归算法_递归_02之间的递归关系,以及边界值。
具体实践中,我自己总结的方法论是“小而大之”和“大而小之”两个步骤。
所谓小而大之,就是将具体问题扩展成一般问题,而待求解的问题只是更一般问题的一个具体情况。
大而小之,就是要对这个一般问题,考虑它非常小的情形。从小的情况得到边界值以及递归关系的信息。对解决问题是非常有帮助的。

首先,对于python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03皇后问题,有python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03个皇后,且棋盘的大小也是python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03.

当规模确定后,可以把python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03皇后的解法问题看成是逐步生成的。首先放置第一列,解为python八皇后 回溯 python八皇后问题递归算法_函数式编程_07,然后放置第二列,解为python八皇后 回溯 python八皇后问题递归算法_八皇后问题_08,直至求出python八皇后 回溯 python八皇后问题递归算法_函数式编程python八皇后 回溯 python八皇后问题递归算法_函数式编程返回的是列表的列表,每个子列表代表一种解法。

对于python八皇后 回溯 python八皇后问题递归算法_函数式编程,当python八皇后 回溯 python八皇后问题递归算法_递归_12时,代表放置第一列,那么将有python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03种解法,结果为python八皇后 回溯 python八皇后问题递归算法_函数式编程_07:
[[1], [2], [3], …, [n]]
python八皇后 回溯 python八皇后问题递归算法_python八皇后 回溯_15时,对python八皇后 回溯 python八皇后问题递归算法_递归_16中的每一种解法添加第python八皇后 回溯 python八皇后问题递归算法_八皇后问题_03列的放法,首先将所有可能的放法都添加进去,将得到python八皇后 回溯 python八皇后问题递归算法_函数式编程_18种放法,然后过滤掉其中不满足要求的放法,就可以得到python八皇后 回溯 python八皇后问题递归算法_函数式编程

Big question 的解法如下:

def solution(n):
	scale = n
    def f(k):
        if k == 1:
            return [[x] for x in range(1, scale + 1)]
        else:
            last = f(k-1)
            return list(filter(safe, [x+[y] for x in last for y in range(1, scale+1)]))
    return f(n)

其中safe函数用来判断当前的放法是否满足要求,联想函数式编程的思想,safe只要具备判断一解法是否合法即可,与其具体实现是无关的。

在由python八皇后 回溯 python八皇后问题递归算法_函数式编程python八皇后 回溯 python八皇后问题递归算法_递归_02时,要判断新添加的列是否满足要求,只需满足两个条件:

  • 不与之前的任一个皇后同行
  • 不与之前的任一个皇后在同一斜线上
    下面是safe函数的定义:
def safe(x):
    for i in range(len(x)-1):
        if (x[-1] == x[i]) or (abs(x[-1] - x[i]) == (len(x)-1) - i):
            return False
    return True

然后我们把safe函数的定义放到solution函数的内部即可,以形成一种所谓的块结构

def solution(n):
	scale = n
	
	def safe(x):
    	for i in range(len(x)-1):
        	if (x[-1] == x[i]) or (abs(x[-1] - x[i]) == (len(x)-1) - i):
           	 return False
    	return True
    
    def f(k):
        if k == 1:
            return [[x] for x in range(1, scale + 1)]
        else:
            last = f(k-1)
            return list(filter(safe, [x+[y] for x in last for y in range(1, scale+1)]))
    return f(n)

运行如下:

>>>len(solution(8))
92
>>>[len(solution(x)) for x in range(1, 10)]
[1, 0, 0, 2, 10, 4, 40, 92, 352]