Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.9k views
in Technique[技术] by (71.8m points)

performance - Finding the longest non-negative sub array

I'm looking for an more efficient alternative to brute force for finding the longest sub array of an array with a non-negative sum. The numbers range from -5 to 5 in this array.

For example, if you have an array A:

4 2 -5 3 0 -2 -2 -3 4 -4 -3 -2 1

then the longest non-negative sub array is

4 2 -5 3 0 -2 -2 -3 4, with the length of 9

The solution I'm thinking of is to keeping tack of a best solution, and a best suffix, where the best suffix always ends with the last point checked A[i]. If the best suffix is ever longer than best solution, we update the best solution to the best suffix.

The suffix would be made of a negative subarray sandwiched between two positive sub arrays. So, in this case starting from left to right:

4 2 is the first positive sub array -5 is the negative sub array 3 0 -2 is second positive sub array

Then the program checks if the sum of two positive sub arrays is larger than the negative sub array. If so, the whole best suffix becomes the new first positive sub arrays. If not, then the first positive and negative sub array are dumped and the second positive sub array becomes the first sub array, and so on.

In theory the program should be able to incrementally check for the best solution in linear time.

But this answer seems to be incorrect.

So Im looking for a better solution for this, or at-least a hint towards a better direction

Any help would be appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is called the "longest biased interval" and is a common problem in biology. Here is the algorithm (where in your case L==0):

Input: A nonempty array of n real numbers `A[1 . . . n]` and a lower bound `L`.

Output: The start and end index of the longest segment of `A` with sum at least `L`.

C[0 . . . n] and M[0 . . . n] are arrays of size n +1, as defined in the context.

M[0]←C[0]←0; x←y←0;
for i←1 to n do
    C[i]←C[i ?1] + A[i];
    if C[i ?1]<C[M[i ?1]] then M[i]←i ?1 else M[i] = M[i ?1];
    k←i ?y +x ? 1;
    while k >0 do
        if C[i] ? C[M[k]] >= L then k←M[k] else break;
        x←k +1; y←i;
    end while
    OUTPUT A(x, y);
end for

See Chen, Kuan-Yu, and Kun-Mao Chao. "Optimal algorithms for locating the longest and shortest segments satisfying a sum or an average constraint." Information Processing Letters 96.6 (2005): 197-201.

Here is an illustration of the concept:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...