Saya memiliki antrian prioritas di Java of Integers:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
Ketika saya menelepon pq.poll()
saya mendapatkan elemen minimum.
Pertanyaan: bagaimana cara mengubah kode untuk mendapatkan elemen maksimal?
java
collections
priority-queue
Borut Flis
sumber
sumber
Jawaban:
Bagaimana kalau seperti ini:
The
Collections.reverseOrder()
menyediakanComparator
yang akan mengurutkan unsur-unsur diPriorityQueue
dalam urutan yang berlawanan untuk tatanan alam mereka dalam kasus ini.sumber
Collections.reverseOrder()
juga kelebihan beban untuk mengambil pembanding, jadi ini juga berfungsi jika Anda membandingkan objek khusus.PriorityQueue(Comparator<? super E> comparator)
.Anda dapat menggunakan ekspresi lambda sejak Java 8.
Kode berikut akan mencetak 10, lebih besar.
Fungsi lambda akan mengambil dua bilangan bulat sebagai parameter masukan, menguranginya satu sama lain, dan mengembalikan hasil aritmatika. Fungsi lambda mengimplementasikan Antarmuka Fungsional
Comparator<T>
,. (Ini digunakan di tempat, sebagai lawan dari kelas anonim atau implementasi terpisah.)sumber
(x, y) -> y - x
mungkin tidak sesuai untuk bilangan bulat panjang karena melimpah. Misalnya, bilangan y = Integer.MIN_VALUE dan x = 5 menghasilkan bilangan positif. Lebih baik digunakannew PriorityQueue<>((x, y) -> Integer.compare(y, x))
. Padahal, solusi yang lebih baik diberikan oleh @Edwin Dalorzo untuk digunakanCollections.reverseOrder()
.Anda dapat memberikan
Comparator
objek khusus yang memberi peringkat elemen dalam urutan terbalik:Sekarang, antrian prioritas akan membalikkan semua perbandingannya, jadi Anda akan mendapatkan elemen maksimum daripada elemen minimum.
Semoga ini membantu!
sumber
if (rhs < lhs) return +1;
if (rhs > lhs) return -1;
if (lhs < rhs) return +1; if (lhs > rhs) return -1;
sumber
b-a
dapat menyebabkanoverflow
jadi harus menghindari menggunakannya dan harus menggunakanCollections.reverseOrder();
sebagai pembanding atau mengganti ba denganInteger.compare(a,b);
yang telah ditambahkan diJava 8
Di Java 8+ Anda dapat membuat antrian prioritas maksimal melalui salah satu metode berikut:
Metode 1:
Metode 2:
Metode 3:
sumber
Unsur-unsur antrian prioritas diurutkan menurut urutan aslinya, atau oleh Pembanding yang disediakan pada waktu konstruksi antrian.
Pembanding harus mengganti metode perbandingan.
Metode perbandingan default mengembalikan bilangan bulat negatif, nol, atau bilangan bulat positif karena argumen pertama kurang dari, sama dengan, atau lebih besar dari yang kedua.
Default PriorityQueue yang disediakan oleh Java adalah Min-Heap, Jika Anda ingin max heap berikut adalah kodenya
Referensi: https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#comparator ()
sumber
Berikut adalah contoh Max-Heap di Java:
Outputnya akan menjadi 10
sumber
Ini dapat dicapai dengan kode di bawah ini di Java 8 yang telah memperkenalkan konstruktor yang hanya membutuhkan pembanding.
sumber
Anda dapat menggunakan
MinMaxPriorityQueue
(ini adalah bagian dari pustaka Guava): berikut dokumentasinya . Sebagai gantinyapoll()
, Anda perlu memanggilpollLast()
metode tersebut.sumber
Ubah PriorityQueue menjadi MAX PriorityQueue Metode 1: Queue pq = new PriorityQueue <> (Collections.reverseOrder ()); Metode 2: Antrian pq1 = new PriorityQueue <> ((a, b) -> b - a); Mari kita lihat beberapa Contoh:
Mari kita ambil wawancara terkenal Masalah: Kth Largest Element in an Array menggunakan PriorityQueue
Cara lain :
Seperti yang bisa kita lihat, keduanya memberikan hasil yang sama.
sumber
Ini dapat dicapai dengan menggunakan
sumber
Saya baru saja menjalankan simulasi Monte-Carlo pada kedua komparator pada tumpukan ganda jenis min max dan keduanya sampai pada hasil yang sama:
Ini adalah komparator maksimal yang telah saya gunakan:
(A) Koleksi pembanding bawaan
(B) Pembanding khusus
sumber
if (rhs < lhs) return +1;
if (rhs> lhs) return -1;Anda dapat mencoba sesuatu seperti:
Yang berfungsi untuk fungsi perbandingan dasar lainnya yang mungkin Anda miliki.
sumber
sumber
Anda dapat mencoba mendorong elemen dengan tanda terbalik. Misalnya: Untuk menambahkan a = 2 & b = 5 dan kemudian polling b = 5.
Setelah Anda mengumpulkan kepala antrian, balikkan tanda untuk penggunaan Anda. Ini akan mencetak 5 (elemen yang lebih besar). Dapat digunakan dalam implementasi yang naif. Jelas bukan perbaikan yang andal. Saya tidak merekomendasikannya.
sumber
Kita bisa melakukan ini dengan membuat kelas CustomComparator kita yang mengimplementasikan antarmuka Comparator dan mengganti metode perbandingannya. Di bawah ini adalah kode yang sama:
sumber