3

I was asked the following question in an interview and I couldn't give the optimal answer to this.

Problem: Write a program that can find the length of the largest contiguous sub-array that sums up to S. Given an array of variable size and an Integer.

Input: 1. An array of variable size, which can have only {-1, 0, 1} elements.

Example: A[] = {1, 0, 0, 1, -1, 1, 1, 1, 1}

  1. An integer S,

Example: S = 4

Output: 8

Explanation: Largest contiguous sub-array of A that adds up to S=4: {1, 0, 0, 1, -1, 1, 1, 1} or {0, 0, 1, -1, 1, 1, 1, 1}

Constraint: Should complete in O(N)

I have solved the problem, but couldn't meet the time complexity. Can anyone help with a solution that can solve this in O(N).

PS: No Copyright issues with the question that I have asked.

kishoredbn
  • 2,007
  • 4
  • 28
  • 47

3 Answers3

3

Iterate though the array storing the total sum up to the current element in a variable. For each sum value, put it in a hash table in O(1) (if it isn't already there), mapping to which index it appeared.

But, before each insert, check if the hash table already contains current_sum - S. If it contains, that means that the subarray [previous_index+1..current_index] has sum S.

That works even if the array contains elements other than {-1, 0, 1}.

Here's an example Python code:

def solve(A, S):
    table = {0: 0}
    answer = None
    total = 0
    for i, x in enumerate(A):
        total += x
        if total - S in table:
            candidate = (table[total-S], i)
            if answer is None or candidate[1] - candidate[0] > answer[1] - answer[0]:
                answer = candidate
        if total not in table: 
            table[total] = i+1

    return answer

print solve([-1, 0, 1, 1, 1, 1, 1, 0, 0, 1], 4)
Juan Lopes
  • 10,143
  • 2
  • 25
  • 44
  • this code output (4,15), means the answer length is 15? – shole Mar 02 '16 at 03:58
  • @shole No, it means the string starting at index 4 and ending at index 15 is the longest. The answer is, actually 15-4+1 = 12. – Juan Lopes Mar 02 '16 at 14:04
  • @JuanLopes seems like your solution do not work for all scenarios. Here is one solve([-1, 0, 1, 1, 1, 1, 1, 0, 0, 1], 4). – kishoredbn Mar 05 '16 at 01:07
  • 1
    @ikis you're right, but I think 0 is a special case, since it's the only one you can achieve from an empty array. So it's just a matter of putting 0:0 in the table in the beginning. (already edited) – Juan Lopes Mar 05 '16 at 02:29
1

If the only three values are -1, 0, and 1, then you can solve the problem by counting the number of values that are -1, 0 and 1. And then applying a formula. Something to the effect of:

  • Take all the 0s.
  • Be sure you have enough 1s (for positives, -1s for negatives).
  • If not, error out.
  • Then choose the right number of 1s/-1s so you use up all of the "other values"

The last point is intentionally a bit vague (you can think about it by working out some examples).

The key point is that with three values, you can populate the three values. Then you can use some rules to get the longest appropriate sum.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
1

Outline of the algorithm:

  1. Define Lo[x] be the Length of longest prefix sum which sum to x
  2. Define Sh[x] be the Length of the shortest prefix sum which sum to x
  3. Ans = max(Lo[x+S] - Sh[x]) for all x, which can be found by loop the array once

Lo[] & Sh[] both has memory size of O(n) because of the fact that all element is in {-1,0,1}

To handle the negative sum, one of the methods is to map range -n..n to 0..2n so that the index x can represent (The size of both array is thus O(2n) = O(n))

To calculate the prefix sum, just loop through the array once, and update the arrays, both Lo[] & Sh[] can be calculated in O(n)

shole
  • 4,046
  • 2
  • 29
  • 69