Array A[] contains only \'1\' and \'-1\'
Construct array B, where B[i] is the length of the longest continuous subarray starting at j and ending at i, where j
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<int> solve(const vector<int> &A)
{
int n = A.size();
int sum = 0;
int min = 0;
vector<int> 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<int> B(n,-1);
for (int i=0; i!=n; ++i) {
sum += A[i];
if (sum<min) {
min = sum;
low_points.push_back(i);
// low_points[-sum] will be the index where the sum was first
// reached.
}
else if (sum>min) {
// 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;
}
You can consider the sum of +1/-1, like on my graph. We start at 0 (it doesnt matter).
So: you want, when considering anything point, to get the at left other point which is most far, and below it.
1 construct and keep the sum
It takes n iterations : O(n)
2 construct a table value=>point, iterating every point, and keeping the most at left:
You get: 0 => a, 1 => b (not d), 2 => c (not e,i,k), 3 => f (not h), 4 => g (not m), 5 => n, 6 => o
It takes n iterations : O(n)
3 at each level (say 0, 1, 2, 3, ...) => you keep the point most far, which is below it:
level 0 => a
level 1 => a
etc. => it will be always a.
Suppose graph begins at point g:
4 => g
3 => h
2 => i
5 => g
6 => g
Then: if a point is just over 3 (then 4: as m) => it will be h
It takes also n operations at max (height of the graph precisely).
4 iterate each point: your B[i].
At each point, say h : sum = 3, you take the most far below it (table of operation 3): in my schema it is always a = 0;
Suppose graph begins at point g:
for points
g, h, i, k => nothing
j => i
l => i
m => h
n => g
You can combine some operations in the same iteration.