эффективное отсортированное Декартовое произведение 2 отсортированных массива целых чисел

нужно подсказки для разработки эффективного алгоритма, который принимает следующий вход и выплевывает следующий выход.

Input: два отсортированных массива целых чисел A и B, каждый длиной n

вывод: один отсортированный массив, состоящий из декартовых произведений массивов A и B.

For Example: 

Input:
A is 1, 3, 5
B is 4, 8, 10
here n is 3.

Output:
4, 8, 10, 12, 20, 24, 30, 40, 50

вот мои попытки решить эту проблему.

1) учитывая, что выход n^2, эффективный алгоритм не может сделать лучше, чем O (n^2) Время сложность.

2) Сначала я попробовал простой, но неэффективный подход. Создайте Декартовое произведение A и B. Это можно сделать в o(n^2) сложности времени. нам нужно хранить, так что мы можем сделать сортировку по нему. Поэтому o (n^2) сложность пространства тоже. Теперь мы сортируем n^2 элементов, которые нельзя сделать лучше, чем O(n^2logn), не делая никаких предположений о входе.

наконец, у меня есть O(n^2logn) время и O (n^2) алгоритм сложности пространства.

должен быть лучший алгоритм потому что я не использовал отсортированный природа входных массивов.

2 ответов


Если есть решение, которое лучше, чем O (n2 log n) он должен сделать больше, чем просто использовать тот факт, что A и B уже отсортированы. См. мой ответ на этот вопрос.


Шрикант удивляется, как это можно сделать в O (n) пространство (не считая пространства для вывода). Это можно сделать, лениво генерируя списки.

предположим, что мы имеем A = 6,7,8 и B = 3,4,5. Во-первых, умножьте каждый элемент в A первым элементом в B и сохраните их в списке:

6×3 = 18, 7×3 = 21, 8×3 = 24

найти наименьший элемент этого списка (6×3), вывести его, заменить его на этот элемент в раз следующий элемент в B:

7×3 = 21, 6×4 = 24, 8×3 = 24

найдите новый наименьший элемент этого списка (7×3), выведите его и замените:

6×4 = 24, 8×3 = 24, 7×4 = 28

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


Если вы умножите значение A на все значения B, список результатов все равно будет отсортирован. В вашем примере:

A - 1, 3, 5

B - 4, 8, 10

1*(4,8,10) = 4,8,10

3*(4,8,10) = 12,24,30

теперь вы можете объединить два списка (точно так же, как в сортировке слиянием). Вы просто смотрите на обе головки списка и помещаете меньшую в список результатов. Итак, здесь вы выберете 4, затем 8, затем 10 и т. д. результат = 4,8,10,12,24,30

теперь вы делаете то же самое для списка результатов и следующего оставшегося списка, объединяя 4,8,10,12,24,30 с 5*(4,8,10) = 20,40,50.

поскольку слияние наиболее эффективно, если оба списка имеют одинаковую длину, вы можете изменить эту схему, разделив A на две части, выполнить слияние рекурсивно для обеих частей и объединить оба результата.

обратите внимание, что вы можете сэкономить время, используя подход слияния, поскольку не требуется, чтобы a сортировался, просто B должен быть отсортирован.