在数组

时间:2016-03-14 01:20:21

标签: algorithm divide-and-conquer lis

任何人都可以帮我解决这个问题,我一直试图解决这个问题。

假设有一个数组A [1,2 ... n]的数字,我们希望用Divide an Conquer方法找到增长最长的连续子序列。具体地,我们希望找到索引i,j使得i <= j且A [i] <= A [i + 1] <= ..... A [j]。例如,如果数组有4,1,3,5,6,7,5,8,2那么它必须返回[1,3,5,6,7]。

我已经搜索了很多关于这个问题但我能找到的只有动态方法和没有连续元素的最长增加子序列。

2 个答案:

答案 0 :(得分:1)

分而治之的解决方案可以通过将数组划分为2来完成,例如A 1 和A 2 。然后,一旦递归地解决了两个子阵列的问题,就应该考虑原始阵列的最优解可能存在的场景。

选项1:最长的连续增加子序列完全在A 1 中,在这种情况下,您已经找到了最大长度或相关答案,或者它是什么你打算回来。

选项2:同样,最长的连续增加子序列完全在A 2 中。

选项3:最长的连续增加子序列部分在A 1 中,部分在Array 2 中。在这种情况下,考虑A 1 是数组的左边部分而A 2 是右边部分,你基本上必须从交叉点左转,直到它没有减少或者你到达A 1 的左端。然后你在A 2 右转,直到它没有增加或你到达它的右端。

在这些选项中,你选择一个长度最长的选项,然后你就完成了。

但是,我应该注意,分而治之不是这个问题的最佳解决方案,因为它具有 O(nlogn)时间复杂度。正如Jon Bentley的着名书籍Programming Pearls中所提到的,他所谓的最大和连续子序列问题的解决方案已知具有线性时间复杂。该解决方案可以很容易地适应处理增加的子序列,而不是最大总和。

该算法基于Bentley调用扫描的方法,它基于任何子序列必须结束的想法。

这种方法非常简单,下面可以找到Python实现。

def maxIncreasing(arr):
    maxLength = 1
    maxStart = 0
    curStart = 0
    curLength = 1
    for i in range(1, len(arr)):
        if arr[i] <= arr[i-1]:
            if curLength > maxLength:
                maxLength = curLength
                maxStart = curStart
            curStart = i
            curLength = 1
        else:
            curLength += 1
    if curLength > maxLength:
        maxLength = curLength
        maxStart = curStart
    return (maxLength, maxStart)

答案 1 :(得分:0)

这个怎么样:

  1. 将数组A分为A1和A2。

  2. 找到子阵列A1和A2的最长连续子序列,分别命名为s1,s2。

  3. 如果最长的连续子序列与A1和A2交叉,则连续的子序列必须使用A1的最后一个和A2的第一个,命名为s3。

  4. 比较s1,s2,s3,找到最长的。

  5. 在第2步中,它需要不断划分子阵列。第3步和第4步是征服过程。