Вопрос с интервью: три массива и O (N * N)

Предположим, что у нас есть три массива длиной N, которые содержат произвольные числа типа long. Затем нам присваивается число M (того же типа), и наша задача состоит в том, чтобы выбрать три числа A, B и C один из каждого массива (другими словами A должен быть выбран из первого массива, B из второго и C из третьего) поэтому сумма A + B + C = M.

Вопрос: можно выбрать все три числа и в конечном итоге со временем выполнить O (N 2)?


Иллюстрация:

Массивы:

1) 6 5 8 3 9 2
2) 1 9 0 4 6 4
3) 7 8 1 5 4 3

И M нам дано 19. Тогда наш выбор будет состоять из 8 первых, 4 из второго и 7 из третьего.

Ответ 1

Это можно сделать в O (1) пространстве и O (N 2) времени.

Сначала давайте разрешим более простую задачу:
Для двух массивов A и B выберите один элемент из каждого, чтобы их сумма была равна заданному числу K.

Сортируйте оба массива, которые принимают O (NlogN).
Наведите указатели i и j, чтобы i указывал на начало массива A и j указывает на конец B.
Найдите сумму A[i] + B[j] и сравните ее с K

  • если A[i] + B[j] == K мы нашли пара A[i] и B[j]
  • если A[i] + B[j] < K, нам нужно увеличьте сумму, поэтому приращение i.
  • если A[i] + B[j] > K, нам нужно уменьшите сумму, поэтому декремент j.

Этот процесс нахождения пары после сортировки принимает O (N).

Теперь давайте возьмем исходную задачу. Теперь у нас есть третий массив C.

Итак, теперь алгоритм:

foreach element x in C
  find a pair A[i], B[j] from A and B such that A[i] + B[j] = K - x
end for

Внешний цикл запускает N раз, и для каждого прогона мы выполняем операцию O (N), которая делает весь алгоритм O (N 2).

Ответ 2

Вы можете свести его к аналогичной проблеме с двумя массивами, которая известна и имеет простое решение O (n) (с использованием итерации с обоих концов).

  • Сортировка всех массивов.
  • Попробуйте каждое число A из первого массива один раз.
  • Найти, если последние два массива могут дать нам числа B и C, такие, что B + C = M - A.

Шаги 2 и 3 умножают сложность O (n ^ 2).

Ответ 3

Другие решения уже лучше, но здесь мое O (n ^ 2) время и O (n) решение памяти в любом случае.

Вставьте все элементы массива C в хэш-таблицу. (временная сложность O (n), пространство O (n)) Возьмем все пары (a, b), a из A и b из B (временная сложность O (n ^ 2)). Для каждой пары проверьте, существует ли M-(a + b) в hastable (сложность O (1), ожидаемая для каждого запроса).

Таким образом, общая временная сложность O (n ^ 2) и пространственная сложность O (n) для хэш-таблицы.

Ответ 4

Хешировать последний список. Время, затраченное на это, - это O (N) в этом конкретном списке, но это будет добавлено к следующей фазе.

Следующий этап - создать "матрицу" первых двух строк их сумм. Затем найдите хэш, если их соответствующий номер есть. Создание матрицы - O (N * N), а поиск в хеше - постоянное время.

Ответ 5

У меня есть решение. Вставьте все элементы из одного из списка в хеш-таблицу. Это не займет время O (n).

Как только это будет завершено, вы найдете все пары из оставшихся 2 массивов и посмотрите, присутствует ли их сумма в хеш-таблице.

Поскольку хеш-связь является постоянной, мы получаем квадратичное время.

Используя этот подход, вы сохраняете время при сортировке.

Еще одна идея: если вы знаете максимальный размер каждого элемента, вы можете использовать вариацию сортировки ведра и делать это в nlogn time.

Ответ 6

1.Store A [i] * B [j] для всех пар (i, j) в другом массиве D, организованном в хэш-структуре данных. Сложностью этого шага является O (N * N).

construct a hash named D
for i = 1 to n
    for j = 1 to n
        insert A[i]*B[j] into D

2. Для каждого C [i] в ​​массиве C найдите, существует ли M-C [i] в ​​D. Сложность этого шага - O (N).

for i = 1 to n
    check if M - C[i] is in D

Ответ 7

За счет пространства O (N ^ 2), но используя O (N ^ 2) время, можно обрабатывать массивы four, вычисляя все возможные суммы из первых двух массивов, и все возможные остатки из последних двух, сортировать списки (возможно в линейном времени, так как они все типа "long", число бит которых не зависит от N), а затем видя, равна ли любая сумма любому остатку.

Ответ 8

Сортировка всех 3 массивов и использование двоичного поиска - лучший подход. После сортировки массивов нужно обязательно искать двоичный поиск, а не линейный поиск, который принимает n, а не log (n).

Хэш-таблица также является жизнеспособным вариантом.

Комбинация хэшей и сортировки может привести к сокращению времени, но по стоимости пространства O (N квадратных).

Ответ 9

У меня есть еще одна временная сложность O(N^2), O(N) дополнительное решение для пространственной сложности.

Сначала отсортируйте три массива, этот шаг O(N*log(N)). Затем для каждого элемента из A создайте два массива V = Ai + B и W = Ai + C (Ai - текущий элемент). Ai + B означает, что каждый элемент этого нового массива V является элементом в этой позиции в B plus Ai (текущий элемент в A). W = Ai + C аналогичен.

Теперь слияние V и W, как в сортировке слияния. Поскольку оба сортируются, это O(N). В этом новом массиве с элементами 2*N найдите M + Ai (потому что Ai используется дважды). Это можно сделать в O(log n) с бинарным поиском.

Поэтому общая сложность O(N^2).

Ответ 10

Сортировка трех массивов. Затем инициализируйте три индекса

  • i, указывающий на первый элемент из A,
  • j, указывающий на последний элемент B и
  • k, указывающий на первый элемент C. Хотя i, j, k находятся в пределах их соответствующих массивов A, B, C

  • Если A [i] + B [j] + C [k] == M return

  • Если A [i] + B [j] + C [k] M.Increment i, если A [i] <= C [k] в противном случае приращение k.

  • Если A [i] + B [j] + C [k] > M. Decrement j.

который должен работать в O (n).

Ответ 11

Как насчет:

for a in A
 for b in B
  hash a*b

for c in C
 if K-c is in hash
   print a b c

Идея состоит в том, чтобы хэшировать все возможные пары в и B. Далее для каждого элемента в C следует, если остаточный zum присутствует в хеше.