Dies ist eine interessante Frage, die ich im Internet gefunden habe. Bei einem Array mit n Zahlen (ohne Informationen darüber) sollten wir das Array in linearer Zeit vorverarbeiten, damit wir die k kleinsten Elemente in der O (k) -Zeit zurückgeben können, wenn wir eine Zahl 1 <= k erhalten <= n
Ich habe dieses Problem mit einigen Freunden diskutiert, aber niemand konnte eine Lösung finden. Jede Hilfe wäre dankbar!
Kurznotizen: - Die Reihenfolge der k kleinsten Elemente ist nicht wichtig - Die Elemente im Array sind Zahlen, können ganze Zahlen sein und sind möglicherweise nicht (also keine Grundsortierung) - Die Zahl k ist in der Vorverarbeitungsphase nicht bekannt. Die Vorverarbeitung ist O (n) -Zeit. die Funktion (finde k kleinste Elemente) auf O (k) Zeit.
Antworten:
Verarbeiten Sie das Array von Werten in der Zeit O ( n ) vor :n O(n)
Die Gesamtzeit ist innerhalb precomputationO(1+2+4+...+n)⊆O(n)
Beantworten Sie eine Anfrage nach den kleinsten Elementen in A in der Zeit O ( k ) :k A O(k)
enthält die k kleinsten Elemente.A[1..k] k
Verweise:
quelle
Der Einfachheit halber sei . Verwenden Sie den linearen Zeitauswahlalgorithmus, um die Elemente an den Positionen 2 m - 1 , 2 m - 2 , 2 m - 3 , … , 1 zu finden . Dies dauert lineare Zeit. Wenn k gegeben ist , finde t so, dass 2 t - 1 ≤ k ≤ 2 t ist ; beachte, dass 2 t ≤ 2 k ist . Filtern Sie alle Elemente mit einem Rang von höchstens 2 t herausn=2m 2m−1,2m−2,2m−3,…,1 k t 2t−1≤k≤2t 2t≤2k 2t Verwenden Sie nun den linearen Zeitauswahlalgorithmus, um das Element an der Position in der Zeit O ( 2 t ) = O ( k ) zu finden .k O(2t)=O(k)
Klarstellung: Es scheint, dass die Vorverarbeitung Zeit in nimmt takes ( n log n ) , und das ist in der Tat der Fall, wenn Sie nicht vorsichtig sind. So führen Sie die Vorverarbeitung in linearer Zeit durch:Θ(nlogn)
Die In-Place-Partitionierung erfolgt wie bei QuickSort. Die Laufzeit ist linear in und somit linear. Am Ende erfüllt das Array A die folgende Eigenschaft: Für jedes k besteht A [ 0 .. n / 2 k - 1 ] aus den n / 2 k kleinsten Elementen.n+n/2+n/4+⋯+1<2n A k A[0..n/2k−1] n/2k
quelle
Verwenden Sie zuerstO(n) , um einen Min-Heap zu erstellen. Es ist bekannt, dass wir O(k) , um das k zu findenk kleinsten Elemente in einem Min-Heap zu finden:
Frederickson, Greg N. , Ein optimaler Algorithmus zur Auswahl in einem Min-Heap , Inf. Comput. 104, Nr. 2, 197-214 (1993). ZBL0818.68065 ..
quelle
quelle