给出两个数字数组

时间:2015-10-14 16:32:35

标签: algorithm

给定两个数组a [1],...,a [n]和b [1],...,b [n],其中每个数字为0或1,写一个取Θ的算法( n)找到最大跨度(i,j)的时间和空间,使得a [i] + a [i + 1] + .... a [j] = b [i] + b [i + 1] + ..... b [j]或报告没有这样的跨度。

我遇到了这个程序:

    #include <stdio.h>
    #define size 100 //assume n is less than 100
    int main()
    {
    int n, a[size], b[size]; 
    int start[2*size], end[2*size];
    int sum1 = 0, sum2 = 0, i;
    int diff[size];
    printf("Enter n: ");
    scanf("%d", &n);
    for(i = 0; i < n; i++)
    {
        printf("Enter a[%d]: ", i);
        scanf("%d", &a[i]);
    }
    for(i = 0; i < n; i++)
    {
        printf("Enter b[%d]: ", i);
        scanf("%d", &b[i]);
    }

    for(i = 0; i < n; i++)
    {
        if(a[i]) sum1++;
        if(b[i]) sum2++;
        diff[i] = sum1 - sum2;
    }
    for(i = 0; i < 2*n; i++)
        start[i] = -1;
    start[n] = end[n] = 0;  //initially sum is 0 at the beginning of array and the first n-1 elements of start and end are used if sum of A till ith element is less than sum of B till ith element
    for(i=0; i < n; i++)
    {
        if(start[diff[i] + n] == -1)
            start[diff[i] + n] = i;
        end[diff[i] + n] = i;
    }
    int max = -1;
    int savei = -1; //savei is for storing the sum having the largest span

    for(i = 0; i < 2*n; i++)
    {
        if(start[i] > -1 && (end[i] - start[i] > max))
        {
            max = end[i] - start[i];
            savei = i;
        }

    }
    if(savei >= 0)
    {
        printf("The largest span is from %d to %d\n", start[savei]+(savei != n), end[savei]);
    //when sum zero is having the largest span, span starts from first element itself. Else, the span starts from the next element from which the span does not change
    }
    else
    {
        printf("No span\n");
    }
}

我无法理解这个算法是如何工作的。请帮我理解这一点。

据我所知,程序计算到目前为止a的总和与b的总和之间的差异。我们将Start初始化为-1并将start [n]和end [n]设置为0.在此之后,我不知道为什么程序会执行它的功能。

1 个答案:

答案 0 :(得分:0)

这就是这个想法。

定义pre_a[i] = a[0]+a[1]+...+a[i]pre_b[i] = b[0]+b[1]+...+b[i]

我们什么时候有a[i]+a[i+1]+...+a[j] = b[i]+b[i+1]+...+b[j]? 我们在pre_a[j]-pre_a[i-1]=pre_b[j]-pre_b[i-1]或等效pre_a[j]-pre_b[j]=pre_a[i-1]-pre_b[i-1]时拥有此功能。

如果我们现在定义diff[i] = pre_a[i]-pre_b[i],我们可以看到我们的问题实际上是j>idiff[j] == diff[i-1]j-i是最大的。由于diff[i]的范围超过[-n,n],因此对于k中的每个[-n,n],我们可以计算出最大j哪个diff[j]=k,哪个是j最小diff[i]=kend(分别存储在startend[k]-start[k]中)。剩下要做的就是找到-n<=k<=n的最大if(_count!=0 && _count!=1 && item<_lowbound) { _order = false; } if(_count!=0 && _count!=1 && item>_lowbound) { _order = true; }