Pronalaženje najboljih K elemenata u Java nizu
1. Pregled
U ovom uputstvu implementirat ćemo različita rješenja problema pronalaženje k najveći elementi u nizu s Javom. Za opisivanje vremenske složenosti koristit ćemo Big-O notaciju.
2. Brute-Force rješenje
Grubo rješenje ovog problema je iterirati kroz zadani niz k puta. U svakoj iteraciji, mi ćemonaći najveću vrijednost. Tada ćemo ukloniti ovu vrijednost iz niza i staviti na izlazni popis:
javni popis findTopK (Unos popisa, int k) {Niz popisa = novi ArrayList (ulaz); Popis topKList = novi ArrayList (); za (int i = 0; i <k; i ++) {int maxIndex = 0; for (int j = 1; j array.get (maxIndex)) {maxIndex = j; }} topKList.add (array.remove (maxIndex)); } return topKList; }
Ako pretpostavimo n da bude veličina datog niza, vremenska složenost ovog rješenja je O (n * k). Nadalje, ovo je najneučinkovitije rješenje.
3. Pristup Java zbirkama
Međutim, postoje učinkovitija rješenja za ovaj problem. U ovom ćemo odjeljku objasniti dva od njih pomoću Java zbirki.
3.1. TreeSet
TreeSet ima Crveno-crno drvostruktura podataka kao okosnica. Kao rezultat, stavljanje vrijednosti ovom skupu košta O (zapisnik n). TreeSet je sortirana zbirka. Stoga možemo stavite sve vrijednosti u TreeSetiizvadi prvu k od njih:
javni popis findTopK (Unos popisa, int k) {Postavi sortedSet = novi TreeSet (Comparator.reverseOrder ()); sortedSet.addAll (ulaz); vrati sortedSet.stream (). limit (k) .collect (Collectors.toList ()); }
The vremenska složenost ovog rješenja je O (n * log n). Iznad svega, ovo bi trebalo biti učinkovitije od grube sile ako k ≥ log n.
Važno je to upamtiti TreeSet ne sadrži duplikate. Kao rezultat, rješenje radi samo za ulazni niz s različitim vrijednostima.
3.2. PriorityQueue
PriorityQueue jeHrpastruktura podataka na Javi. Uz njegovu pomoć, možemo postići O (n * log k) riješenje. Štoviše, ovo će biti brže rješenje od prethodnog. Zbog navedenog problema, k je uvijek manja od veličine polja. Dakle, to znači O (n * log k) ≤ O (n * log n).
Algoritam ponavlja se jednom kroz zadani niz. U svakoj iteraciji na hrpu ćemo dodati novi element. Također, držat ćemo veličinu hrpe manjom ili jednakom k. Dakle, morat ćemo ukloniti dodatne elemente iz hrpe i dodati nove. Kao rezultat, nakon iteriranja kroz niz, hrpa će sadržavati k najveće vrijednosti:
javni popis findTopK (Unos popisa, int k) {PriorityQueue maxHeap = novi PriorityQueue (); input.forEach (number -> {maxHeap.add (number); if (maxHeap.size ()> k) {maxHeap.poll ();}}); Popis topKList = novi ArrayList (maxHeap); Collections.reverse (topKList); povratak topKList; }
4. Algoritam odabira
Postoji mnogo pristupa rješavanju zadanog problema. I, iako je to izvan opsega ovog vodiča, koristeći pristup algoritma za odabirbit će najbolji jer daje linearnu vremensku složenost.
5. Zaključak
U ovom uputstvu opisali smo nekoliko rješenja za pronalaženje k najveći elementi u nizu.
Kao i obično, primjer koda dostupan je na GitHubu.