寻找阵列中最长的几何级数

时间:2014-05-07 17:50:53

标签: java python algorithm dynamic-programming

我正在尝试实现动态编程算法来查找列表中最长几何级数的长度。我遇到了这个算法: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。任何对我做错的帮助都会非常有帮助。

1 个答案:

答案 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):完全匹配伪代码,尽管这不是错误的原因。