O (NlogN) находит 3 числа, которые имеют сумму любого произвольного T в массиве

Учитывая массив A целых чисел, найдите любые 3 из них, которые суммируются с любым заданным T.

Я видел это в каком-то онлайн-сообщении, которое утверждает, что оно имеет решение O (NlogN).

Для двух чисел я знаю, что хэш-таблица может помочь для O (N), но для 3 чисел я не могу ее найти.

Я также чувствую, что эта проблема звучит знакомо с некоторыми сложными проблемами, но не может вспомнить имя и, следовательно, не может использовать Google. (В то время как наихудшим является, очевидно, O (N ^ 3), и с решением для 2 чисел это действительно O (N ^ 2))

На самом деле он ничего не решает в реальном мире, просто меня беспокоит..

Любая идея?

Ответы

Ответ 1

Я думаю, что ваша проблема эквивалентна проблеме 3SUM.

Ответ 3

Проблема 2SUM может быть решена в O (nlgn) времени.

Сначала отсортируйте массив, который занимает не более O (nlgn) операций. Теперь на i-й итерации мы выбрали элемент a[i] и найдем элемент -a[i] в оставшейся части массива (т.е. От i+1 до n-1), и этот поиск может быть выполнен в двоичном поиске, который занимает не более lgn время. Таким образом, в целом он будет выполнять операции O (nlgn).

Но проблема 3SUM не может быть решена в O (nlgn) времени. Мы могли бы свести его к O (n ^ 2)

Ответ 4

Звучит как вопрос о домашнем задании...

Если вы можете найти два значения, которые суммируются с N, но вы хотите расширить поиск до трех значений, не могли бы вы для каждого значения M в наборе искать два значения, которые суммируются (N - M)? Если вы можете найти два значения, которые суммируются с определенным значением в O (log N), то это будет O (N log N).

Ответ 6

Поднят непосредственно из https://en.wikipedia.org/wiki/3SUM

    sort(S);

    for i=0 to n-3 do

        a = S[i];
        start = i+1;

        end = n-1;

        while (start < end) do

           b = S[start];
           c = S[end];
           if (a+b+c == 0) then
              output a, b, c;
              // Continue search for all triplet combinations summing to zero.
               start = start + 1
               end = end - 1

           else if (a+b+c > 0) then
              end = end - 1;
           else
              start = start + 1;
           end
        end
     end