Python 带孔最长算术级数

Python 带孔最长算术级数,python,algorithm,Python,Algorithm,最长算术级数子序列问题如下。给定一个整数数组A,设计一个算法来寻找其中最长的算术级数。换句话说,找到一个序列i1

最长算术级数子序列问题如下。给定一个整数数组A,设计一个算法来寻找其中最长的算术级数。换句话说,找到一个序列i1
#/usr/bin/env python
导入系统
def算法(arr):
n=长度(arr)
如果(n=0和k2*arr[j]):
L[i][j]=2
i-=1
其他:
L[i][j]=L[j][k]+1
llap=最大值(llap,L[i][j])
i=i-1
k=j+1
而(i>=0):
L[i][j]=2
i-=1
返回视差
arr=[1,4,5,7,8,10]
打印算法(arr)
这将输出
4

但是,我希望能够找到丢失最多一个值的算术级数。因此,如果arr=[1,4,5,8,10,13],我希望它报告长度为5的级数,其中缺少一个值

这能有效地完成吗?

根据我对的回答改编
n
A
的长度,
d
是范围,即最大项目减去最小项目

A = [1, 4, 5, 8, 10, 13]    # in sorted order
Aset = set(A)

for d in range(1, 13):
    already_seen = set()
    for a in A:
        if a not in already_seen:
            b = a
            count = 1
            while b + d in Aset:
                b += d
                count += 1
                already_seen.add(b)
            # if there is a hole to jump over:
            if b + 2 * d in Aset:
                b += 2 * d
                count += 1
                while b + d in Aset:
                    b += d
                    count += 1
                    # don't record in already_seen here
            print "found %d items in %d .. %d" % (count, a, b)
            # collect here the largest 'count'
我相信这个解决方案仍然是
O(n*d)
,只是常数比没有孔的情况下更大,尽管两个嵌套的“for”循环中有两个“while”循环。实际上,将值固定为
d
:这样我们就进入了运行
n次的“a”循环;但是内部两个while循环中的每一个在
a
的所有值上总共运行最多
n
次,再次给出了复杂性
O(n+n+n)=O(n)


与原始解决方案一样,此解决方案适用于以下情况:您对绝对最佳答案不感兴趣,而只对步长相对较小的子序列感兴趣
d
:例如
n
可能为1'000'000,但您只对步长的子序列感兴趣,最多为1'000。然后你可以让外循环在1'000处停止。

@Keyser有一个序列1、4、7、10、13,但7不见了。哦,我没意识到你允许数字之间有间隙:)如果你设置了你的表,这样你就不只是按“最后一个索引”和“最后一个元素”索引,而且序列是否已经有间隙了呢@DennisMeng这也是我的第一个想法,但当前两个元素之间存在差距时,会有一些诡计。[1,5]可以是4-list的前两个元素,也可以是2-list的第一个和第三个元素,其中一个元素已经丢失,并且在2D数组中只有一个点来存储这两条信息。
A = [1, 4, 5, 8, 10, 13]    # in sorted order
Aset = set(A)

for d in range(1, 13):
    already_seen = set()
    for a in A:
        if a not in already_seen:
            b = a
            count = 1
            while b + d in Aset:
                b += d
                count += 1
                already_seen.add(b)
            # if there is a hole to jump over:
            if b + 2 * d in Aset:
                b += 2 * d
                count += 1
                while b + d in Aset:
                    b += d
                    count += 1
                    # don't record in already_seen here
            print "found %d items in %d .. %d" % (count, a, b)
            # collect here the largest 'count'