简体   繁体   English

数组中最长连续序列的分治法

[英]Divide and Conquer algorithm for Longest Increasing Consecutive sequence in an array

Can anyone help me out with this problem that I have been trying to solve for a while. 任何人都可以帮助我解决我已经尝试解决一段时间的问题。

Lets say there is an array A[1,2...n] of numbers and we wish to find the longest increasing consecutive sub sequence with Divide an Conquer method. 假设有一个数字数组A [1,2 ... n],我们希望使用Divide an Conquer方法找到增长最长的连续子序列。 Specifically we wish to find indices i,j such that i<=j and A[i]<=A[i+1]<=.....A[j]. 具体来说,我们希望找到索引i,j,使得i <= j并且A [i] <= A [i + 1] <= ..... A [j]。 For Example if the array has 4,1,3,5,6,7,5,8,2 then it has to return [1,3,5,6,7]. 例如,如果数组具有4,1,3,5,6,7,5,8,2,则它必须返回[1,3,5,6,7]。

I have searched a lot about this problem but all I can find is dynamic approach and Longest Increasing Subsequences without consecutive elements. 我已经搜索了很多有关此问题的内容,但是我只能找到动态方法和最长连续子序列而没有连续元素。

How about this: 这个怎么样:

  1. Divide array A to A1 and A2. 将数组A分为A1和A2。

  2. Find the longest consecutive sub sequence of sub array A1 and A2, named as s1, s2 respectively. 查找子数组A1和A2最长的连续子序列,分别命名为s1,s2。

  3. If the longest consecutive sub sequence cross A1 and A2, the consecutive sub sequence must use the last of A1 and first of A2, named as s3. 如果最长的连续子序列穿过A1和A2,则连续的子序列必须使用A1的最后一个和A2的第一个,名为s3。

  4. Compare s1, s2, s3, find the longest one. 比较s1,s2,s3,找到最长的一个。

  5. In step 2, it needs divide sub arrays constantly. 在第2步中,需要不断划分子数组。 And step 3 and 4 are conquer process. 而步骤3和4是征服过程。

A divide-and-conquer solution can be done by dividing the array into 2, say A 1 and A 2 . 可以通过将数组划分为2(即A 1和A 2)来完成分而治之的解决方案。 Then, once having recursively solved the problem for the two sub-arrays, you should consider the scenarios in which the optimal solution to the original array may lie. 然后,一旦递归解决了两个子阵列的问题,则应考虑可能存在对原始阵列的最佳解决方案的方案。

Option 1: The longest contiguous increasing subsequence is completely in A 1 , in which case you already found the maximum length, or the relevant answer, or whatever it is you are planning to return. 选项1:最长的连续递增子序列完全在A 1中 ,在这种情况下,您已经找到了最大长度或相关的答案,或计划返回的值。

Option 2: Similarly, the longest contiguous increasing subsequence is entirely in A 2 . 选项2:同样,最长的连续递增子序列完全在A 2中

Option 3: The longest contiguous increasing subsequence is partially in A 1 and partially in Array 2 . 选项3:最长的连续递增子序列部分位于A 1中 ,部分位于数组2中 In this case, considering A 1 is the left portion of the array and A 2 is the right portion, you basically have to go left from the intersection until it is not decreasing or you reach the left end of A 1 . 在这种情况下,考虑到A 1是数组的左侧部分,而A 2是右侧部分,则基本上必须从交点处向左走,直到交点不减小或到达A 1的左端为止。 And then you go to right on A 2 until it is not increasing or you reach the right end of it. 然后在A 2上向右转到,直到它没有增加或到达它的右端。

Among these options you take the one with the greatest length, and you're done. 在这些选项中,您将选择长度最大的一个,然后就完成了。

However, I should note that divide-and-conquer is not the optimal solution to this problem, as it has O(nlogn) time complexity. 但是,我应该指出,分治法不是解决此问题的最佳方法,因为它具有O(nlogn)时间复杂度。 As mentioned in Jon Bentley's notable book, Programming Pearls , a solution what he calls as the maximum sum contiguous subsequence problem is known to have linear time complexity. 如乔恩·本特利(Jon Bentley)的著名著作《 编程珍珠 》( Programming Pearls )所述,他称之为最大和连续子序列问题的解决方案具有线性时间复杂度。 That solution may easily be adapted to handle increasing subsequences, instead of the maximum sum. 该解决方案可以容易地适于处理增加的子序列,而不是最大和。

The algorithm is based on an approach Bentley calls scanning, and it is based on the idea that any subsequence has to end at some point. 该算法基于Bentley称为扫描的方法,并且基于任何子序列都必须在某个点结束的想法。

The approach is painfully simple, and a Python implementation can be found below. 该方法非常简单,可以在下面找到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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM