Вопрос с интервью: три массива и 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 присутствует в хеше.