假设我有一个数字递增的序列,我想找到序列中最长算术级数的长度。最长的算术级数意味着具有共同差异的递增序列,例如[2,4,6,8]或[3,6,9,12]。
例如,
对于[5, 10, 14, 15, 17]
,[5, 10, 15]
是最长的算术级数,长度为3;
[10, 12, 13, 20, 22, 23, 30]
,,[10, 20, 30]
是长度为3的最长算术级数;
[7, 10, 12, 13, 15, 20, 21]
的,[10, 15, 20]
或[7, 10, 13]
是长度为3的最长算术进度。
这个网站 https://prismoskills.appspot.com/lessons/Dynamic_Programming/Chapter_22_-_Longest_arithmetic_progression.jsp 提供了对问题的一些见解,即通过循环j并考虑 每3个元素。我打算在Python中使用这个算法,我的代码如下:
def length_of_AP(L):
n = len(L)
Table = [[0 for _ in range(n)] for _ in range(n)]
length_of_AP = 2
# initialise the last column of the table as all i and (n-1) pairs have lenth 2
for i in range(n):
Table[i][n-1] =2
# loop around the list and i, k such that L[i] + L[k] = 2 * L[j]
for j in range(n - 2, 0, -1):
i = j - 1
k = j + 1
while i >= 0 and k < n:
difference = (L[i] + L[k]) - 2 * L[j]
if difference < 0:
k = k + 1
else:
if difference > 0:
i = i - 1
else:
Table[i][j] = Table[j][k] + 1
length_of_AP = max(length_of_AP, Table[i][j])
k = k + 1
i = i - 1
return length_of_AP
此功能适用于[1,3,4,5,7,8,9],但它不适用于[5,10,14,15,20,25,26,27, 28,30,31],我应该得到6但我得到4.我可以看到原因是列表中的25,26,27,28可能是我的功能分散注意力的因素。如何更改我的功能,以便为我提供所需的结果。
任何帮助都可能会受到赞赏。
答案 0 :(得分:0)
你试过吗? 这是一个快速强力实施,对于小型数据集,它应该足够快地运行:
def gen(seq):
diff = ((b-a, a) for a, b in it.combinations(sorted(seq), 2))
for d, n in diff:
k = []
while n in seq:
k.append(n)
n += d
yield (d, k)
def arith(seq):
return max(gen(seq), key=lambda x: len(x[1]))
In [1]: arith([7, 10, 12, 13, 15, 20, 21])
Out[1]: (3, [7, 10, 13])
In [2]: %timeit arith([7, 10, 12, 13, 15, 20, 21])
10000 loops, best of 3: 23.6 µs per loop
In [3]: seq = {random.randrange(1000) for _ in range(100)}
In [4]: arith(seq)
Out[4]: (171, [229, 400, 571, 742, 913])
In [5]: %timeit arith(seq)
100 loops, best of 3: 3.79 ms per loop
In [6]: seq = {random.randrange(1000000) for _ in range(1000)}
In [7]: arith(seq)
Out[7]: (81261, [821349, 902610, 983871])
In [8]: %timeit arith(seq)
1 loop, best of 3: 434 ms per loop
答案 1 :(得分:0)
按照链接并运行第二个示例,看起来代码实际上找到了正确的LAP
5,10,15,20,25,30,
但找不到合适的长度。我没有花太多时间分析代码而是分析
// Any 2-letter series is an AP
// Here we initialize only for the last column of lookup because
// all i and (n-1) pairs form an AP of size 2
for (int i=0; i<n; i++)
lookup[i][n-1] = 2;
对我来说很可疑。您似乎需要使用2而不是最后一列初始化整个 lookup
表,如果我这样做,它也会开始在您的示例上获得正确的长度。
所以摆脱&#34;初始化&#34;循环并将第3行更改为以下代码:
# initialise whole table with 2 as all (i, j) pairs have length 2
Table = [[2 for _ in range(n)] for _ in range(n)]
而且他们的
样品执行:
最大AP长度= 6
3,5,7,9,11,13,15,17,
也包含这个错误,实际上只是因为运气好而打印出正确的序列。如果我将sortedArr修改为
int sortedArr[] = new int[] {3, 4, 5, 7, 8, 9, 11, 13, 14, 15, 16, 17, 18, 112, 113, 114, 115, 116, 117, 118};
我得到以下输出
最大AP长度= 7
112,113,114,115,116,117,118,
这显然是错误的,因为原始的8项长序列3, 5, 7, 9, 11, 13, 15, 17,
仍在那里。