我正在尝试实现动态编程算法来查找列表中最长几何级数的长度。我遇到了这个算法:http://www.cs.illinois.edu/~jeffe/pubs/pdf/arith.pdf并尝试修改它以获得几何级数。但是,我无法让它发挥作用。
我的代码是:
def dp(numbers):
numbers = sorted(numbers)
n = len(numbers)
table = [[2] * n] * n
for i in range(n):
table[i][n - 1] = 2
largest = 2
for j in range(n - 1, -1, -1):
i = j - 1
k = j + 1
while i >= 0 and k <= n - 1:
if numbers[j] > math.sqrt(numbers[i] * numbers[k]):
k += 1
elif numbers[j] < math.sqrt(numbers[i] * numbers[k]):
table[i][j] = 2
i -= 1
elif numbers[j] == math.sqrt(numbers[i] * numbers[k]):
table[i][j] = table[j][k] + 1
largest = max(largest, table[i][j])
i -= 1
k += 1
while i >= 0:
table[i][j] = 2
i -= 1
return largest
例如,如果我运行print dp([1, 2, 4, 8, 16, 32, 64])
,那么当它应该是7时我会得到4。任何对我做错的帮助都会非常有帮助。
答案 0 :(得分:2)
问题在于:
table = [[2] * n] * n
这样做是一个由n个元素列表组成的列表n次。问题是,由于它们是相同的(is
- 相同的,而不仅仅是==
- 相同的)列表而不是副本,它们都会一起更新,这很糟糕,例如,
>>> lst=[[2]]*2
>>> lst
[[2], [2]]
>>> lst[0]==lst[1]
True
>>> lst[0]is lst[1]
True
>>> lst[0][0]=1
>>> lst
[[1], [1]]
修复是写
table = [[2] * n for i in range(n)]
重复运行[2] * n
以获取n个副本,这些副本最初为==
- 相同但不是is
- 相同。
>>> lst=[[2]for i in range(2)]
>>> lst
[[2], [2]]
>>> lst[0]==lst[1]
True
>>> lst[0]is lst[1]
False
>>> lst[0][0]=1
>>> lst
[[1], [2]]
编辑:此外,for j in range(n - 1, -1, -1):
应该for j in range(n - 2, -1, -1):
完全匹配伪代码,尽管这不是错误的原因。