最大产品子序列

时间:2013-05-28 17:34:03

标签: algorithm

我需要按n整数的顺序找到子序列的最大乘积。我正在寻找一种算法,不一定表示为代码。

示例:

  1. 在:3,1,-2,4。出:4。
  2. In:2,5,-1,-2,-4。出:20。(2 * 5 * -1 * -2)。
  3. 我已在O(n²)中完成了算法,但现在我需要O(n)中的算法 我知道这是可能的。

    如何在O(n)

    中完成此操作

2 个答案:

答案 0 :(得分:5)

如果您的所有输入都是> 0,通过将所有数字相乘得到最大乘积。

如果您的所有输入都是非0并且偶数均为负数,则再次通过将所有数字相乘来找到最大乘积。

因此,工作是处理零和负数。

您需要通过列表一次,随时计算正在运行的产品。   如果你达到0,那么之前的所有内容都是一个候选子集,如果它比迄今为止发现的最好,那么需要保存其详细信息(起始索引,结束索引,产品)。现在开始一个新的运行产品。   如果您达到负数,则该项是您的总计中的条件中断。 不使用负数的运行产品将被评估为最佳状态。但是现在你需要有2个正在运行的产品,一个是负数而另一个是新产品。因此,后续乘法需要对2个列表起作用。此时我将有2个正在运行的产品。如果你打另一个负数,你的每个运行列表都需要按照之前的描述进行二分。如果你不修剪,你可能会得到很多运行列表。我认为你可以修剪运行列表只跟踪3:刚启动的子列表,带有奇数负数的连续列表和偶数奇数的负数。任何候选子列表都不是正在进行的乘法的一部分,应该在放弃它之前评估它是最好的。

最后是O(n)

答案 1 :(得分:2)

一组非零数字的最大子序列乘积是所有数字的乘积(如果有偶数个负数),或者它是第一个负数后所有数字的乘积中的较大者,以及所有数字的乘积,直至最后一个负数。

这为您提供了O(N)解决方案:将序列分解为非零数字的运行,并将第一段中的规则应用于每个。选择最大值。

类似C的Python代码:

def prod(seq, a, b):
    r = 1
    for i in xrange(a, b):
        r *= seq[i]
    return r

def maxprodnon0(seq, a, b):
    firstneg = -1
    negs = 0
    for i in xrange(a, b):
        if seq[i] >= 0: continue
        negs += 1
        if firstneg < 0:
            firstneg = i
        lastneg = i
    if negs % 2 == 0: return prod(seq, a, b)
    return max(prod(seq, firstneg + 1, b), prod(seq, a, lastneg))

def maxprod(seq):
    best = 0
    N = len(seq)
    i = 0
    while i < N:
        while i < N and seq[i] == 0:
            i += 1
        j = i
        while j < N and seq[j] != 0:
            j += 1
        best = max(best, maxprodnon0(seq, i, j))
        i = j
    return best

for case in [2,5,-1,-2,-4], [1,2,0,-4,5,6,0,7,1], [1,2,0,-4,5,6,-1,-1,0,7,1]:
    print maxprod(case)