Я думаю о разных решениях для одной проблемы. Предположим, у нас есть K отсортированных связанных списков, и мы объединяем их в один. Все эти списки вместе имеют N элементов.
Хорошо известным решением является использование очереди приоритетов и выталкивание / отправка первых элементов из каждого списка, и я могу понять, почему это занимает O(N log K)
время.
Но давайте посмотрим на другой подход. Предположим, у нас есть некоторая процедура MERGE_LISTS(LIST1, LIST2)
, которая объединяет два отсортированных списка, и это займет O(T1 + T2)
время, где T1
и T2
означают LIST1
и LIST2
размеры.
То, что мы делаем сейчас, обычно означает объединение этих списков и объединение их попарно (если число нечетное, последний список, например, можно игнорировать на первых шагах). Обычно это означает, что мы должны создать следующее «дерево» операций слияния:
N1, N2, N3...
обозначает LIST1, LIST2, LIST3
размеры
O(N1 + N2) + O(N3 + N4) + O(N5 + N6) + ...
O(N1 + N2 + N3 + N4) + O(N5 + N6 + N7 + N8) + ...
O(N1 + N2 + N3 + N4 + .... + NK)
Кажется очевидным, что будет log(K)
этих строк, каждая из которых реализует O(N)
операций, поэтому время для операции MERGE(LIST1, LIST2, ... , LISTK)
будет фактически равно O(N log K)
.
Мой друг сказал мне (два дня назад), что это займет O(K N)
время. Итак, вопрос - я где-то нашелся или он на самом деле не прав? И если я прав, почему этот подход «разделяй и властвуй» нельзя использовать вместо подхода с приоритетной очередью?