给定两个数组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.在此之后,我不知道为什么程序会执行它的功能。
答案 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>i
,diff[j] == diff[i-1]
和j-i
是最大的。由于diff[i]
的范围超过[-n,n]
,因此对于k
中的每个[-n,n]
,我们可以计算出最大j
哪个diff[j]=k
,哪个是j
最小diff[i]=k
,end
(分别存储在start
和end[k]-start[k]
中)。剩下要做的就是找到-n<=k<=n
的最大if(_count!=0 && _count!=1 && item<_lowbound)
{
_order = false;
}
if(_count!=0 && _count!=1 && item>_lowbound)
{
_order = true;
}
。