Maximum Contiguous Subsequence Sum of At Least Length L

后端 未结 5 1978
北海茫月
北海茫月 2020-12-01 01:53

So for the following array, where L = 3

-5 -1 2 -3 0 -3 3

The best possible sum of at least length 3 would be 0, where the subsequence is t

5条回答
  •  春和景丽
    2020-12-01 02:16

    This is possible to do using dynamic programming in O(n).

    1.) Store the partial sums up to i for each index i in the array

    2.) Store the index of the minimum sum up to i

    3.) Store the maximum up to i for each index i in the array, which is the partial sum up to i minus the partial sum with the index determined in step 2, which is Min(Sum(k)) k <=i keeping in mind the constraint that the sub sequence must be at least of length L.

    All of this can be done in O(n) in one loop.

    Now that you have the maximum sums up to i for each index i in the array you can determine the maximum sum of the contiguous sub sequence and the end index of that sub sequence. When you have the end index, you can just walk backwards until you have reached that maximum sum. Both of these operations are also O(n).

    Sample implementation in C#:

    int [] values = {-5, -1, 2, -3, 0, -3, 3};
    int L = 3;
    
    int[] sumUpTo = new int [values.Length];
    int[] minUpTo = new int[values.Length];
    int[] maxUpTo = new int[values.Length];
    
    for (int i = 0; i < values.Length; i++)
    {
        sumUpTo[i] = values[i];
        minUpTo[i] = i;
        if (i > 0)
        {
            sumUpTo[i] += sumUpTo[i - 1];
            minUpTo[i] = sumUpTo[i] < sumUpTo[i - 1] ? i : minUpTo[i - 1];
        }
        maxUpTo[i] = sumUpTo[i] - ((i >= L && sumUpTo[minUpTo[i - L]] < 0) ? sumUpTo[minUpTo[i - L]] : 0);
    }
    
    
    int maxSum = int.MinValue;
    int endIndex = -1;
    
    for (int i = L-1 ; i < values.Length; i++)
        if(maxUpTo[i] > maxSum)
        {
            endIndex = i;
            maxSum = maxUpTo[i];
        }
    
    //Now walk backwards from maxIndex until we have reached maxSum
    int startIndex = endIndex;
    int currentSum = values[startIndex];
    
    while (currentSum != maxSum || (endIndex - startIndex < L-1))
    {
        startIndex--;
        currentSum += values[startIndex];
    
    }
    
    Console.WriteLine("value of maximum sub sequence = {0}, element indexes {1} to {2}", maxSum, startIndex, endIndex);
    

提交回复
热议问题