Wednesday, September 17, 2014

Largest Span

GATE 2006 : Given two arrays of numbers a1,...,an and b1,...bn where each number is 0 or 1, the fastest algorithm to find the largest span(i, j) such that
ai+ai+1+ ... + aj = bi + bi+1 + ... + bj 


#include <stdio.h>
#include <malloc.h>
void printArray(int *a, int start, int end)
{
    while(start++ <= end)
        printf("%d ", a[start-1]);
    printf("\n");
}
void changeStartEnd(int *a, int *b, int *start, int *end, int *sum, int *next1)
{//O(1)
    if(b[*start]==1 && a[*start]==0)
        ++*start;
    else if(b[*end]==1 && a[*end]==0)
        --*end;
    else if(b[*start]==a[*start])
        ++*start;
    else if(b[*end]==a[*end])
        --*end;
    else if(next1[sum[*end-1]] > next1[sum[*start]])
        --*end;
    else
        ++*start;
}
void largestSpan(int *a, int *b, int n)
{
    int    *sumA = malloc(n*sizeof(int));
    int    *sumB = malloc(n*sizeof(int));
    int  *next1A = malloc(n*sizeof(int));
    int  *next1B = malloc(n*sizeof(int));
    int *onePtrA = malloc(n*sizeof(int));
    int *onePtrB = malloc(n*sizeof(int));
    int i, j, k, start=1, end=n-1, diffA, diffB;
    sumA[0]=0; sumB[0]=0;
  
    for (i=1, k=1, j=1; i<n ;i++)
    {
        sumA[i]=sumA[i-1]+a[i];
        sumB[i]=sumB[i-1]+b[i];
        if(a[i]==1)
            onePtrA[k++]=i;
        if(b[i]==1)
            onePtrB[j++]=i;
    } //O(n)
    for(i=1; i<k-1; i++)//O(n)
        next1A[i]=sumB[onePtrA[i+1]-1]-sumB[onePtrA[i]];
    for(i=1; i<j-1; i++)//O(n)
        next1B[i]=sumA[onePtrB[i+1]-1]-sumA[onePtrB[i]];
  
    for(i=1; i<n; i++)
    {
        diffA=sumA[end]-sumA[start-1];
        diffB=sumB[end]-sumB[start-1];
        if(diffA == diffB)
            break;
        if (diffB > diffA)
            changeStartEnd(a, b, &start, &end, sumA, next1A);//O(1)
        else
            changeStartEnd(b, a, &start, &end, sumB, next1B);//O(1)
    }//O(n)
    printf("%d, %d\n", start, end);
    printArray(a, start, end);
    printArray(b, start, end);
}
void main()
{
    int b[14]={0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1}; // One based indexing
    int a[14]={0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0}; // One based indexing
    largestSpan(a, b, 14);
}

Hence it takes ϴ(n) time and space