我正在尝试解决N-Queues 如下:
class Solution(object):
def __init__(self):
self.queues = []
def DFS(self, n, row, col, pie, na, path):
if row == n:
print 'current recursion path: ', path
self.queues.append(path)
print 'paths within the recursion: ', self.queues
return
for c in range(n):
if (c not in col) and (c + row not in pie) and (row-c not in na):
col.add(c)
pie.add(c+row)
na.add(row-c)
# self.queues.append(c)
# path += str(c)
path.append(c)
# print 'row: ', row, 'col: ', c, path
self.DFS(n, row + 1, col, pie, na, path)
col.remove(c)
pie.remove(c+row)
na.remove(row-c)
# path = path[:-1]
path.pop()
# else:
# path.pop()
return None
# print '\n'
def solveNQueens(self, n):
"""
:type n: int
:rtype: List[List[str]]
"""
col = set()
pie = set()
na = set()
print 'before recursion: ', self.queues
self.DFS(n, 0, col, pie, na, [])
print 'after recursion: ', self.queues
# return self.reslutPrint(n)
我打印出以下内容:
before recursion: []
current recursion path: [1, 3, 0, 2]
paths within the recursion: [[1, 3, 0, 2]]
current recursion path: [2, 0, 3, 1]
paths within the recursion: [[2, 0, 3, 1], [2, 0, 3, 1]]
after recursion: [[], []]
如您所见,递归为每个路径都获得了正确的答案,但是,答案没有正确地附加到全局变量self.queues
上。你能告诉我为什么会这样吗?
我猜这是由于当我将列表附加到self.queues
时,它会将地址而不是实际值提供给self.queues
。如果是这样,我该如何解决?
非常感谢。
伊恩
答案 0 :(得分:3)
您遇到的问题不是self.queues
,而是您处理path
的方式。将path
传递给函数时,您就是passing it by assignment,而不是它的值。
因此,当您将path
添加到self.queues
并随后执行path.pop()
时,它将影响到引用的path
的任何地方,包括self.queues
。
这是问题的一个简单示例:
>>> a = []
>>> b = [1, 2, 3]
>>> a.append(b)
>>> b.pop()
>>> print(a)
[[1, 2]]
那么,纠正此问题的最佳方法是什么?正如其他人所建议的那样,您可以在添加列表之前用self.queues.append(path[:])
复制。但是我认为仔细检查可以得出另一个答案:将 new path
传递到递归的每个新级别。尝试使用path.append(c)
而不是self.DFS(n, row + 1, pie, na, path + [c]
。这样,您就可以采用一种更具功能性的 不变性方法(可以更进一步,并通过使用不可变数据结构(例如{{1 }})。使用这种方法的代码如下:
tuple
答案 1 :(得分:1)
您是对的,当您追加内容时,您会将列表放入地址self.queues
中。但这不是问题,问题在于您稍后继续修改该对象,因此清空它也意味着self.queues拥有一个指向空列表的指针。
您需要制作路径的副本(例如,通过self.queues.append(path[:]
),并将其附加到队列中。或者在一般情况下,您可以使用python的复制模型(根据您的使用情况https://docs.python.org/2/library/copy.html而定,可以使用浅复制或深复制)