我的N-Queens解决方案出了什么问题?

时间:2018-07-21 18:53:09

标签: python algorithm n-queens

class Solution:
    def solveNQueens(self, n):
        def n_queens_solver(row, visited_cols, unique_y_intercepts, res):
            if row == n:
                results.append(res)
                return 

            for col in range(n):
                if col not in visited_cols and (row + col) not in unique_y_intercepts and (col - row) not in unique_y_intercepts:
                    visited_cols_dup = visited_cols.copy()
                    unique_y_intercepts_dup = unique_y_intercepts.copy()
                    res_dup = res.copy()

                    visited_cols_dup.add(col)
                    unique_y_intercepts_dup.add(row + col)
                    unique_y_intercepts_dup.add(col - row)
                    this_row = '.' * col + 'Q' + '.' * (n - col - 1)
                    res_dup.append(this_row)

                    n_queens_solver(row + 1, visited_cols_dup, unique_y_intercepts_dup, res_dup)

        results = []
        n_queens_solver(0, set(), set(), [])
        return results

我还没有找到解决这个问题的实际方法,我想我的效率很低,但是我不知道我在做什么错。

样本输入:

n = 4

正确的输出:

[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]

我的输出: []

要考虑唯一的对角线,我想出每个有效的位置都要插入一个女王,我们需要考虑斜率+1和斜率-1的所有线。每条线都有一个独特的y轴截距。使用y=x+by=-x+b,插入皇后的每个潜在点都不必具有(y-x == b)或(y+x == b)。

这里我的理由有什么明显的错误之处?

注意-我不是在要求其他或更理想的解决方案。我只是想弄清楚我的思维过程在哪里不正确。

1 个答案:

答案 0 :(得分:4)

算法中的错误如下。查看当您尝试将对角线标记为已访问时会发生什么。

让我们画一个4x4板,并为每个单元分配它所在的正斜对角线的数量(将i + j放在行i和行的正方形上j):

0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6

假设您将第一个皇后放在(1,3)位置。我知道您的算法从第0行开始,但是在这种情况下并不重要。现在,该面板如下所示:

0 1 2 3
1 2 3 Q
2 3 4 5
3 4 5 6

然后将3加到visited_cols,将3 +1 = 4加到y_intercepts,并将3-1 = 2加到y_intercepts。我们有cols = {3}y_intercepts = {2,4}。让我们在板上用X标记与y_intercept的值2对应的对角线:

0 1 X 3
1 X 3 Q
X 3 4 5
3 4 5 6

现在,假设我们对第二行进行算法,然后尝试将第二个皇后放在正方形(2,0)上。这是有效位置,因为第一任皇后不会攻击该广场。但是您的算法将拒绝该位置,因为row + col = 2 + 0 = 2位于y_intercepts集中。发生了什么?我们对正方形(2,0)进行了正斜率测试,但由于y_intercepts集中有2个而失败了。但是请注意,在检查了负斜对角线(记住3-1 = 2?)之后,在此添加了2。因此,对正斜和负斜对角线的测试混合在一起,导致对平方(2,0)的不正确拒绝。这就是为什么您的程序输出空的results向量的原因-在算法的某个点上,存在一行,使得其所有平方都被拒绝(类似于我们刚刚观察到的,某些正方形被正确拒绝,而其他正方形被错误地拒绝了) )。

一种解决方法是为正斜对角线和负斜对角线创建两个单独的集合,并检查row + col是否正斜线和col - row是否负数。