列表子结果方法

时间:2015-06-11 11:20:58

标签: algorithm discrete-mathematics

The Question:

所以,我必须找到连续子集的最大总和,我在python中遵循这个算法。

def SubSeq(list):
    final_list = None
    suming = 0
    for start in range(len(list)):
        for end in range(start+1, len(list)+1):
            subseq = list[start:end]
            summation= sum(list[start:end])
            if summation > suming:
                suming = summation
                final_list = subseq
    return final_list


print SubSeq([5, 15, -30, 10, -5, 40, 10])

我想知道它是否是动态编程中的正确方法,但运行时间为O(n^2)。另外,有没有办法让它成为O(n)

2 个答案:

答案 0 :(得分:0)

这不是动态编程,它是一种强力解决方案。解决方案似乎是正确的,但正如你观察者那样 - 效率低下。

通过应用动态编程可以实现O(n)解决方案,将D(i)表示为以i结尾的最大子连续子数组,并且必须包含i

D(-1) = 0
D(i) = max{ arr[i], D(i-1)

这个想法是,你有两个选择 - 获得以前的"最佳"数组以i-1结尾并向其添加元素i,或创建一个以i开头的新数组。

最后,通过在DP解决方案中应用上述内容,您将获得一个数组,其中每个元素指示以此索引结尾的最大子连续数组,您所要做的就是选择此数组中的最大值以获取最大总和的值,然后返回数组以获得实际的子序列。

示例:

array = 5,15,-30,10,-5,40,10

应用动态编程:

D(-1) = 0
D(0) = 5
D(1) = 20
D(2) = -10
D(3) 10 //because max{-10+10,10} = 10
D(4) = 5
D(5) = 45
D(6) = 55

现在你有阵列:

D = [5,20,-10,10,5,45,55]

最大子序列的值为55,由[10,-5,40,10]给出(跟随上面的数组,然后再返回)

答案 1 :(得分:0)

您基本上是一次又一次地计算总和。您可以通过将总和存储在数组中来避免这种情况。 你可以在O(n)中完成。

设S [0,1..n-1]为序列 设T [0,1,... n-1]为其中T [i]是从第i个元素开始可能的最大连续和的数组。

现在填写T [i],从反向开始。 T [N-1] = MAX(S [N-1],0)
现在T [i] = max(T [i + 1] + S [i],S [i],0)

现在通过'T'数组找到最大总和。

设T [m]为最大值。

计算从S [m]开始的确切序列并添加所有元素,直到总和等于T [m]