# Longest positive subarray

### Question Description

Array A[] contains only ‘1’ and ‘-1’

Construct array B, where B[i] is the length of the longest continuous subsequence starting at j and ending at i, where `j < i and A[j] + .. + A[i] > 0`

Obvious O(n^2) solution would be:

``````for (int i = 0; i < A.size(); ++i) {
j = i-1;
sum = A[i];
while ( j >=0 ) {
sum += A[j];
if (sum > 0)
B[i] = i - j + 1;
--j;
}
}
``````

I’m looking for O(n) solution.

### Practice As Follows

The trick is to realize that we only need to find the minimum j such that `(A[0] + ... + A[j-1]) == (A[0] + ... + A[i]) - 1`. `A[j] + ... + A[i]` is the the same as `(A[0] + ... + A[i]) - (A[0] + ... + A[j-1])`, so once we find the proper j, the sum between j and i is going to be 1.
Any earlier j wouldn’t produce a positive value, and any later j wouldn’t give us the longest possible sequence. If we keep track of where we first reach each successive negative value, then we can easily look up the proper j for any given i.

Here is a C++ implementation:

``````vector solve(const vector &A)
{
int n = A.size();
int sum = 0;
int min = 0;
vector low_points;
low_points.push_back(-1);
// low_points[0] is the position where we first reached a sum of 0
// which is just before the first index.
vector B(n,-1);
for (int i=0; i!=n; ++i) {
sum += A[i];
if (summin) {
// Go back to where the sum was one less than what it is now,
// or go all the way back to the beginning if the sum is
// positive.
int index = sum<1 ? -(sum-1) : 0;
int length = i-low_points[index];
if (length>1) {
B[i] = length;
}
}
}
return B;
}
``````
Tags ,