Longest positive subarray

前端 未结 2 628
再見小時候
再見小時候 2020-12-16 02:41

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

相关标签:
2条回答
  • 2020-12-16 02:48

    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;
    }
    
    0 讨论(0)
  • 2020-12-16 03:04

    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.

    0 讨论(0)
提交回复
热议问题