Was ist die zeitliche Komplexität von Funktionen in heapq library?

9

Meine Frage ist von der Lösung in leetcode unten, ich kann nicht verstehen, warum es O(k+(n-k)log(k)) ist.

Nachtrag: Vielleicht ist die Komplexität nicht so groß, tatsächlich kenne ich die zeitliche Komplexität von heappush() und heappop()

nicht %Vor%     
Ohad Eytan 06.08.2016, 16:06
quelle

1 Antwort

9

heapq ist ein binärer Heap mit O (log n) push und O (log n) pop . Sehen Sie sich den heapq-Quellcode an.

Der von Ihnen angezeigte Algorithmus nimmt O (n log n), um alle Elemente auf den Heap zu schieben, und dann O ((n-k) log n), um das k-te größte Element zu finden. Also wäre die Komplexität O (n log n). Es erfordert auch O (n) zusätzlichen Speicherplatz.

Sie können dies in O (n log k) tun, indem Sie O (k) extra space verwenden, indem Sie den Algorithmus etwas modifizieren. Ich bin kein Python-Programmierer, also müssen Sie den Pseudocode übersetzen:

%Vor%

Der Schlüssel hier ist, dass der Haufen nur die größten bisher gesehenen Elemente enthält. Wenn ein Gegenstand kleiner als der bisher größte k ist, wird er nie auf den Haufen gelegt. Der schlimmste Fall ist O (n log k).

Tatsächlich hat heapq eine heapreplace Methode, also könntest du das ersetzen:

%Vor%

mit

%Vor%

Eine Alternative zum Verschieben der ersten k -Objekte besteht auch darin, eine Liste der ersten k -Elemente zu erstellen und heapify aufzurufen. Ein optimierter (aber immer noch O (n log k)) Algorithmus ist:

%Vor%

Sie könnten auch heapify für das gesamte Array aufrufen, dann die ersten n-k -Objekte aufrufen und dann die oberste:

%Vor%

Das ist einfacher. Ich bin mir nicht sicher, ob es schneller ist als mein vorheriger Vorschlag, aber es verändert das ursprüngliche Array. Die Komplexität ist O (n), um den Heap aufzubauen, und dann O ((n - k) log n) für die Pops. Also ist es O ((n-k) log n). Worst Case O (n log n).

    
Jim Mischel 08.08.2016, 15:29
quelle

Tags und Links