在数组中查找最长的几何级数

Posted

技术标签:

【中文标题】在数组中查找最长的几何级数【英文标题】:Finding Longest Geometric Progression in an Array 【发布时间】:2014-05-07 17:50:53 【问题描述】:

我正在尝试实现一种动态规划算法来查找列表中最长几何级数的长度。我遇到了这个算法: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]),我会得到 4,而它应该是 7。任何关于我做错了什么的帮助都会非常有帮助。

【问题讨论】:

在我看来它不像 Java。我不会想到最长的几何级数会按排序值的顺序排列。例如1,2,3,4,5,6,7,8 将是 4 对于 1,2,4,8 请注意,numbers[j] == math.sqrt(numbers[i] * numbers[k]) 很好,因为 sqrt 已正确舍入,但它看起来很可疑。我可能会写numbers[j] ** 2 == numbers[i] * numbers[k]。另外,我们是否假设为正整数? 是的,我们假设为正整数。你的回答奏效了。非常感谢你! :) 【参考方案1】:

问题出在这里:

table = [[2] * n] * n

它的作用是创建一个由一个 n 元素列表 n 次组成的列表。问题是,由于这些是相同的(is-same,不仅仅是==-same)列表而不是副本,它们都会一起更新,这很糟糕,例如,

>>> 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 个副本,最初是==-same 但不是is-same。

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

【讨论】:

以上是关于在数组中查找最长的几何级数的主要内容,如果未能解决你的问题,请参考以下文章

查找字符串数组中的最长公共前缀

c#查找最长连续子数组第一个和最后一个元素索引

数组篇在python中如何查找最长字符串子串

如何使用Java中的给定字符串值从数组列表中查找最长前缀?

算法——查找:最长连续递增子序列(部分有序)

Java每日算法--编写一个函数来查找字符串数组中的最长公共前缀。