Самый быстрый алгоритм для нахождения наибольшего диапазона (i, j) такой, что ai + ai + 1 + .... + aj = bi + bi + 1 + .... + bj в массивах a и b - PullRequest
0 голосов
/ 03 ноября 2011

Я столкнулся с этой проблемой во время подготовки к экзаменам.

Учитывая два массива чисел a1, ..., an и b1, ...., bn, где каждое число равно 0 или 1, самое быстроеалгоритм, чтобы найти самый большой промежуток (i, j), такой что ai + ai + 1 + .... + aj = bi + bi + 1 + .... + bj или сообщить, что такого промежутка нет.

(A) Принимает O (3 ^ n) и омега (2 ^ n) время, если разрешено хеширование.

(B) Принимает O (n ^ 3) и омега (n ^ 2.5)и время в режиме сравнения ключей

(C) Принимает тета (n) время и пространство

(D) Принимает O (квадратный корень (n)) только в том случае, если сумма 2nэлементы - четное число.

Ответы [ 2 ]

1 голос
/ 31 января 2013

Вот алгоритм O (n),

l=[1,1,1,1,0,1,0,1,1,0,1,0,0,0,1,1,1,1,0]
m=[0,0,0,0,1,0,1,1,1,0,0,0,1,1,1,0,0,0,1]
delta=[]
for i in range(0,len(l)):
    delta.append(l[i]-m[i])

leftsum=[0]
for i in range(1,len(l)+1):
    leftsum.append(leftsum[i-1]+delta[i-1])

sumHash=[-1]*len(l)

maxLen=0;
leftIndex=-1
rightIndex=-1

for i in range(0,len(l)+1):
    if sumHash[leftsum[i]]!=-1:
        if maxLen<i-sumHash[leftsum[i]]:
            maxLen=i-sumHash[leftsum[i]]
            leftIndex=sumHash[leftsum[i]]
            rightIndex=i-1
    else:
        sumHash[leftsum[i]]=i

print 'len=',maxLen,'left=',leftIndex,'right=',rightIndex
1 голос
/ 03 ноября 2011

Единственное решение, которое я могу придумать, - это время O (n ^ 2) и омега (n), если кто-то потрудится сделать правильную проверку. Вероятно, это можно улучшить, если кому-нибудь удастся найти способ использовать все значения, равные 0 и 1.

int[] a = { 1, 1, 0, 1, 1, 0, 1, 0, 1 };
int[] b = { 0, 1, 0, 0, 1, 1, 0, 1, 0 };

int lastSum = 0; int lastI = 0; int lastJ = 0;
int sumA = 0; int sumB = 0; 
for(int i = 0; i < a.Length; i++) // start the sum at [i].
{
    sumA = a[i]; sumB = b[i];
    for (int j = i + 1; j < a.Length; j++) // summing ends on [j]
    //do
    {
        if (sumA == sumB && (lastJ - lastI < j - i))
        {
            lastSum = sumA;
            lastI = i; lastJ = j;
            if (j == a.Length - 1) // you will never find a bigger interval.
            {
                Console.Out.WriteLine("(i, j) = (" + lastI + ", " + lastJ + ")");
                return;
            }
        }
        sumA += a[j];
        sumB += b[j];
    }
}
Console.Out.WriteLine("(i, j) = (" + lastI + ", " + lastJ + ")");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...