簡體   English   中英

最長連續子序列算法

[英]Longest contiguous subsequence algorithm

我有一個具有“偏移”和“長度”屬性的“范圍”對象數組,如下所示。 假設它將按“偏移”升序排序。

范圍數組包含:

Offset        Length     Index
-------       -------    -------
100           10         0
110           2          1 
112           5          2
117           3          3
300           5          4
305           5          5 
400           5          6
405           10         7
415           2          8
417           4          9
421           7          10
428           1          11 
429           6          12  
500           4          13
504           9          14

在這種情況下,連續的子序列將是:

Sequence #1 indices: 0, 1, 2, 3
Sequence #2 indices: 4, 5
Sequence #3 indices: 6, 7, 8, 9, 10, 11, 12  <-- (longest!!)
Sequence #4 indices: 13, 14

假設只有一個最長的序列。 遍歷這些項目,我想為每個連續序列創建一個新數組並返回最大的數組,但這似乎不是最佳的。 有一個更好的方法嗎? 我在 C# 2.0 中實施。 function 應該返回一個包含最長子序列元素的數組,或者返回原始數組中最長子序列的開始和結束索引。

感謝大家對此進行嘗試。

這個問題與連續子序列問題等無關,而是一個可以在 O(n) 時間內解決的簡單問題。 在我看來,數組表示的“字符串”沒有重疊,所以有一個非常簡單的算法:將左手食指放在第一行,然后只要你在連續的范圍內,右手食指就向下運行序列。 當序列結束時,存儲長度和起始位置。 然后重復這個。 每當您發現比上一條記錄更長的序列時,您就會更新起始位置。

一個簡單的線性算法(Python,我確信代碼可以改進):

# Your array
arr = [
  (100, 10), (110, 2), (112, 5), (117, 3), (300, 5), (305, 5), (400, 5), 
  (405, 10), (415, 2), (417, 4), (421, 7), (428, 1), (429, 6), (500, 4),
  (504, 9)
]

# Where does each element end?
ends = map(sum, arr)

s, e = 0, 0 # start and end of longest contiguous subseq
cur = 0     # length of current contiguous subseq
for j, i in enumerate(range(1, len(arr))):
    # See if current element is contiguous with the previous one
    if (arr[i][0] == ends[j]):
        cur += 1
    elif cur > 0:
        # If not, we may have found the end of a (currently) longest subseq
        if cur > (e - s):
            e = j
            s = e - cur

        cur = 0  # reset subseq length

# The longest contiguous subseq may be at the end of the array
if cur > (e - s):
    e = j + 1
    s = e - cur

# print the start and end index of the longest contiguous subseq
print(s, e)

{ java 中的線性時間解,無需動態規划。 最接近的問題是:
需要O(N^2) DP 解的最長遞增子序列。

int LongestContiguousIncreasingSubsequence(int[] a)     
{

   int maxL = 1,currentL=1;
   int n=a.length;

   for ( int i = 0; i < n-1; i++ )
   {
       if(a[i+1]>a[i])
           currentL++;
       else 
       {
           if (currentL>maxL)
               maxL=currentL;
           currentL=1;
       }               
   }       

   return maxL;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM