Jadi inilah solusi O (n log n) di java.
long merge(int[] arr, int[] left, int[] right) {
int i = 0, j = 0, count = 0;
while (i < left.length || j < right.length) {
if (i == left.length) {
arr[i+j] = right[j];
j++;
} else if (j == right.length) {
arr[i+j] = left[i];
i++;
} else if (left[i] <= right[j]) {
arr[i+j] = left[i];
i++;
} else {
arr[i+j] = right[j];
count += left.length-i;
j++;
}
}
return count;
}
long invCount(int[] arr) {
if (arr.length < 2)
return 0;
int m = (arr.length + 1) / 2;
int left[] = Arrays.copyOfRange(arr, 0, m);
int right[] = Arrays.copyOfRange(arr, m, arr.length);
return invCount(left) + invCount(right) + merge(arr, left, right);
}
Ini adalah jenis gabungan yang hampir normal, seluruh sihir disembunyikan dalam fungsi gabungan. Perhatikan bahwa saat menyortir algoritma menghapus inversi. Sementara algoritma penggabungan menghitung jumlah inversi yang dihapus (diurutkan bisa dikatakan).
Satu-satunya momen ketika inversi dihilangkan adalah ketika algoritma mengambil elemen dari sisi kanan sebuah array dan menggabungkannya ke array utama. Jumlah inversi yang dihapus oleh operasi ini adalah jumlah elemen yang tersisa dari larik kiri yang akan digabungkan. :)
Semoga cukup jelas.
left.length - i
ke penghitung inversi? Saya rasa akan masuk akal untuk menambahkan 1, karena Anda termasuk dalam kasus logis di mana perbandingan antara dua subarray memiliki elemen array kiri yang lebih besar daripada yang kanan. Adakah yang bisa menjelaskannya kepada saya seperti saya berusia 5 tahun?arr
. Tapi ini bukan satu pembalikan. Anda menemukan inversi untuk semua elemen dalam larik kiri yang lebih besar dari 6. Dalam kasus kami, ini mencakup 8 juga. Jadi, 2 ditambahkan kecount
, yang sama denganleft.length - i
.Saya telah menemukannya dalam waktu O (n * log n) dengan metode berikut.
Ambil A [1] dan temukan posisinya dalam larik terurut B melalui pencarian biner. Jumlah inversi untuk elemen ini akan menjadi satu kurang dari nomor indeks posisinya di B karena setiap angka yang lebih rendah yang muncul setelah elemen pertama A akan menjadi inversi.
2a. mengakumulasi jumlah inversi untuk melawan variabel num_inversions.
2b. Hapus A [1] dari larik A dan juga dari posisinya yang sesuai di larik B
Berikut adalah contoh dari algoritma ini. Array asli A = (6, 9, 1, 14, 8, 12, 3, 2)
1: Gabungkan sortir dan salin ke array B.
B = (1, 2, 3, 6, 8, 9, 12, 14)
2: Ambil A [1] dan pencarian biner untuk menemukannya dalam larik B
A [1] = 6
B = (1, 2, 3, 6 , 8, 9, 12, 14)
6 ada di posisi ke-4 dari larik B, jadi ada 3 inversi. Kita tahu ini karena 6 berada di posisi pertama dalam larik A, jadi setiap elemen bernilai lebih rendah yang kemudian muncul dalam larik A akan memiliki indeks j> i (karena i dalam kasus ini adalah 1).
2.b: Hapus A [1] dari larik A dan juga dari posisinya yang sesuai dalam larik B (elemen tebal dihilangkan).
A = ( 6, 9, 1, 14, 8, 12, 3, 2) = (9, 1, 14, 8, 12, 3, 2)
B = (1, 2, 3, 6, 8, 9, 12, 14) = (1, 2, 3, 8, 9, 12, 14)
3: Jalankan kembali dari langkah 2 pada larik A dan B. yang baru.
A [1] = 9
B = (1, 2, 3, 8, 9, 12, 14)
9 sekarang berada di posisi ke-5 dari larik B, jadi ada 4 inversi. Kita tahu ini karena 9 berada di posisi pertama dalam larik A, jadi setiap elemen bernilai lebih rendah yang muncul kemudian akan memiliki indeks j> i (karena i dalam kasus ini lagi-lagi 1). Hapus A [1] dari larik A dan juga dari posisinya yang sesuai di larik B (elemen tebal dihilangkan)
A = ( 9 , 1, 14, 8, 12, 3, 2) = (1, 14, 8, 12, 3, 2)
B = (1, 2, 3, 8, 9 , 12, 14) = (1, 2, 3, 8, 12, 14)
Melanjutkan urat ini akan memberi kita jumlah total inversi untuk larik A setelah loop selesai.
Langkah 1 (merge sort) akan membutuhkan O (n * log n) untuk dieksekusi. Langkah 2 akan dieksekusi sebanyak n kali dan pada setiap eksekusi akan melakukan pencarian biner yang membutuhkan O (log n) untuk dijalankan dengan total O (n * log n). Total waktu berjalan akan menjadi O (n * log n) + O (n * log n) = O (n * log n).
Terima kasih atas bantuan Anda. Menuliskan sampel array pada selembar kertas sangat membantu untuk memvisualisasikan masalah.
sumber
Dengan Python
sumber
Saya bertanya-tanya mengapa belum ada yang menyebutkan pohon berindeks biner . Anda dapat menggunakan satu untuk mempertahankan jumlah awalan pada nilai elemen permutasi Anda. Kemudian Anda dapat melanjutkan dari kanan ke kiri dan menghitung untuk setiap elemen jumlah elemen lebih kecil daripada di kanan:
Kompleksitasnya adalah O (n log n), dan faktor konstanta sangat rendah.
sumber
i -= i & -i
baris tersebut? Dan serupai += i & -i
timeit
perbandingan dari semua jawaban Python untuk pertanyaan ini, jadi itu termasuk kode Anda. Anda mungkin tertarik untuk melihat hasil pengaturan waktunya.Sebenarnya saya punya pertanyaan serupa dengan ini untuk pekerjaan rumah. Saya dibatasi bahwa itu harus memiliki efisiensi O (nlogn).
Saya menggunakan ide yang Anda usulkan untuk menggunakan Mergesort, karena efisiensinya sudah benar. Saya baru saja memasukkan beberapa kode ke dalam fungsi penggabungan yang pada dasarnya: Setiap kali angka dari array di sebelah kanan ditambahkan ke array output, saya menambahkan jumlah total inversi, jumlah angka yang tersisa di array kiri.
Ini sangat masuk akal bagi saya sekarang karena saya sudah cukup memikirkannya. Penghitungan Anda berapa kali ada angka yang lebih besar sebelum angka apa pun.
hth.
sumber
Tujuan utama dari jawaban ini adalah untuk membandingkan kecepatan berbagai versi Python yang ditemukan di sini, tetapi saya juga memiliki beberapa kontribusi saya sendiri. (FWIW, saya baru saja menemukan pertanyaan ini saat melakukan pencarian duplikat).
Kecepatan eksekusi relatif dari algoritme yang diimplementasikan di CPython mungkin berbeda dengan yang diharapkan dari analisis algoritme sederhana, dan dari pengalaman dengan bahasa lain. Itu karena Python menyediakan banyak fungsi dan metode yang kuat yang diimplementasikan dalam C yang dapat beroperasi pada daftar dan koleksi lain dengan kecepatan yang mendekati kecepatan seseorang dalam bahasa yang dikompilasi penuh, sehingga operasi tersebut berjalan jauh lebih cepat daripada algoritma setara yang diimplementasikan "secara manual" dengan Python kode.
Kode yang memanfaatkan alat ini sering kali dapat mengungguli algoritme yang secara teoritis lebih unggul yang mencoba melakukan segalanya dengan operasi Python pada item individual dari koleksi. Tentu saja jumlah aktual data yang sedang diproses juga berdampak pada hal ini. Tetapi untuk jumlah data yang moderat, kode yang menggunakan algoritme O (n²) yang berjalan pada kecepatan C dapat dengan mudah mengalahkan algoritme O (n log n) yang melakukan sebagian besar pekerjaannya dengan operasi Python individual.
Banyak jawaban yang diposting untuk pertanyaan penghitungan inversi ini menggunakan algoritme yang didasarkan pada mergesort. Secara teoritis, ini adalah pendekatan yang baik, kecuali jika ukuran lariknya sangat kecil. Tetapi TimSort bawaan Python (algoritme penyortiran stabil hibrid, berasal dari jenis gabungan dan jenis penyisipan) berjalan pada kecepatan C, dan kode gabungan yang dikodekan dengan tangan dengan Python tidak dapat berharap untuk bersaing dengannya untuk kecepatan.
Salah satu solusi yang lebih menarik di sini, dalam jawaban yang diposting oleh Niklas B , menggunakan jenis bawaan untuk menentukan peringkat item array, dan Pohon Berindeks Biner (alias pohon Fenwick) untuk menyimpan jumlah kumulatif yang diperlukan untuk menghitung inversi menghitung. Dalam proses mencoba memahami struktur data ini dan algoritma Niklas, saya menulis beberapa variasi saya sendiri (diposting di bawah). Tetapi saya juga menemukan bahwa untuk ukuran daftar sedang, sebenarnya lebih cepat menggunakan
sum
fungsi bawaan Python daripada pohon Fenwick yang indah.Akhirnya, ketika ukuran daftar mencapai sekitar 500, aspek O (n²) dari panggilan
sum
di dalamfor
loop itu memunculkan kepalanya yang jelek, dan kinerjanya mulai menurun.Mergesort bukan satu-satunya jenis O (nlogn), dan beberapa lainnya dapat digunakan untuk melakukan penghitungan inversi. jawaban prasadvk menggunakan semacam pohon biner, namun kodenya tampaknya dalam C ++ atau salah satu turunannya. Jadi saya telah menambahkan versi Python. Saya awalnya menggunakan kelas untuk mengimplementasikan node pohon, tetapi menemukan bahwa dict terasa lebih cepat. Saya akhirnya menggunakan list, yang bahkan lebih cepat, meskipun itu membuat kodenya sedikit kurang dapat dibaca.
Salah satu bonus dari treesort adalah jauh lebih mudah untuk diimplementasikan secara iteratif daripada mergesort. Python tidak mengoptimalkan rekursi dan ia memiliki batas kedalaman rekursi (meskipun itu dapat ditingkatkan jika Anda benar - benar membutuhkannya). Dan tentu saja pemanggilan fungsi Python relatif lambat, jadi ketika Anda mencoba mengoptimalkan kecepatan, sebaiknya hindari pemanggilan fungsi, jika memungkinkan.
Jenis O (nlogn) lainnya adalah jenis radix terhormat. Keuntungan besarnya adalah tidak membandingkan kunci satu sama lain. Kerugiannya adalah ia bekerja paling baik pada urutan bilangan bulat yang berdekatan, idealnya permutasi bilangan bulat di
range(b**m)
manab
biasanya 2. Saya menambahkan beberapa versi berdasarkan jenis radix setelah mencoba membaca Pembalikan Penghitungan, Penghitungan Jarak Ortogonal Offline, dan Masalah Terkait yang ditautkan dalam menghitung jumlah "inversi" dalam permutasi .Untuk menggunakan pengurutan radix secara efektif untuk menghitung inversi dalam urutan umum dengan
seq
panjang n kita dapat membuat permutasirange(n)
yang memiliki jumlah inversi yang sama denganseq
. Kita dapat melakukannya dalam (paling buruk) waktu O (nlogn) melalui TimSort. Triknya adalah mengubah indeksseq
dengan menyortirseq
. Lebih mudah menjelaskannya dengan contoh kecil.keluaran
Dengan mengurutkan pasangan (nilai, indeks)
seq
kita telah mengubah indeksseq
dengan jumlah swap yang sama yang diperlukan untuk menempatkanseq
urutan aslinya dari urutan yang diurutkan. Kita dapat membuat permutasi itu dengan mengurutkanrange(n)
dengan fungsi kunci yang sesuai:keluaran
Kita dapat menghindarinya
lambda
dengan menggunakan metodeseq
s.__getitem__
:Ini hanya sedikit lebih cepat, tetapi kami sedang mencari semua peningkatan kecepatan yang bisa kami dapatkan. ;)
Kode di bawah ini melakukan
timeit
tes pada semua algoritma Python yang ada di halaman ini, ditambah beberapa dari saya sendiri: beberapa versi brute-force O (n²), beberapa variasi pada algoritma Niklas B, dan tentu saja satu berdasarkan mergesort (yang saya tulis tanpa mengacu pada jawaban yang ada). Ini juga memiliki kode pohon berbasis daftar saya yang secara kasar berasal dari kode prasadvk, dan berbagai fungsi berdasarkan jenis radix, beberapa menggunakan strategi yang mirip dengan pendekatan mergesort, dan beberapa menggunakansum
atau pohon Fenwick.Program ini mengukur waktu eksekusi setiap fungsi pada serangkaian daftar bilangan bulat acak; itu juga dapat memverifikasi bahwa setiap fungsi memberikan hasil yang sama dengan yang lain, dan tidak mengubah daftar input.
Setiap
timeit
panggilan memberikan vektor yang berisi 3 hasil, yang saya urutkan. Nilai utama untuk melihat di sini adalah salah satu minimum, nilai-nilai lain hanya memberikan indikasi tentang bagaimana handal yang nilai minimum, seperti dijelaskan pada Catatan di dalamtimeit
dokumen modul .Sayangnya, keluaran dari program ini terlalu besar untuk dimasukkan dalam jawaban ini, jadi saya mempostingnya di jawabannya (wiki komunitas) sendiri .
Output dari 3 berjalan pada mesin 2GHz single core 32 bit kuno saya yang menjalankan Python 3.6.0 pada distro turunan Debian lama. YMMV. Selama pengujian, saya mematikan browser Web saya dan memutus sambungan dari router saya untuk meminimalkan dampak tugas lain pada CPU.
Proses pertama menguji semua fungsi dengan ukuran daftar dari 5 hingga 320, dengan ukuran loop dari 4096 hingga 64 (karena ukuran daftar berlipat ganda, ukuran loop dibelah dua). Kumpulan acak yang digunakan untuk membuat setiap daftar adalah setengah dari ukuran daftar itu sendiri, jadi kita cenderung mendapatkan banyak duplikat. Beberapa algoritma penghitungan inversi lebih sensitif terhadap duplikat daripada yang lain.
Proses kedua menggunakan daftar yang lebih besar: 640 hingga 10240, dan ukuran loop tetap 8. Untuk menghemat waktu, ini menghilangkan beberapa fungsi paling lambat dari pengujian. Saya brute-force O (n ²) fungsi hanya cara terlalu lambat pada ukuran ini, dan seperti yang disebutkan sebelumnya, kode saya yang menggunakan
sum
, yang tidak begitu baik pada kecil ke daftar moderat, hanya tidak bisa tetap di daftar besar.Proses terakhir mencakup ukuran daftar dari 20480 hingga 655360, dan ukuran loop tetap 4, dengan 8 fungsi tercepat. Untuk ukuran daftar di bawah 40.000 atau lebih, kode Tim Babych adalah pemenangnya. Kerja bagus Tim! Kode Niklas B juga berkinerja serba baik, meskipun dikalahkan pada daftar yang lebih kecil. Kode berbasis dua bagian dari "python" juga bekerja cukup baik, meskipun tampaknya sedikit lebih lambat dengan daftar besar dengan banyak duplikat, mungkin karena
while
perulangan linier yang digunakannya untuk melangkahi penipuan.Namun, untuk ukuran daftar yang sangat besar, algoritme berbasis pembagian dua tidak dapat bersaing dengan algoritme O (nlogn) yang sebenarnya.
Silakan lihat di sini untuk hasilnya
sumber
bisect
adalah C? Saya cukup yakin itu Python.Jumlah inversi dapat ditemukan dengan menganalisis proses penggabungan dalam jenis gabungan:
Saat menyalin elemen dari larik kedua ke larik gabungan (angka 9 dalam contoh ini), ia mempertahankan tempatnya secara relatif terhadap elemen lain. Saat menyalin elemen dari array pertama ke array gabungan (5 di sini) itu dibalik dengan semua elemen tetap berada di array kedua (2 inversi dengan 3 dan 4). Jadi sedikit modifikasi dari merge sort dapat menyelesaikan masalah di O (n ln n).
Sebagai contoh, cukup hapus tanda komentar pada dua baris # dalam kode python mergesort di bawah ini untuk menghitungnya.
EDIT 1
Tugas yang sama dapat dicapai dengan versi stabil pengurutan cepat, yang dikenal sedikit lebih cepat:
Memilih pivot sebagai elemen terakhir, inversi dihitung dengan baik, dan waktu eksekusi 40% lebih baik daripada menggabungkan satu di atas.
EDIT 2
Untuk performa di python, versi numpy & numba:
Pertama bagian numpy, yang menggunakan argsort O (n ln n):
Dan bagian numba untuk pendekatan BIT yang efisien :
sumber
timeit
perbandingan dari semua jawaban Python untuk pertanyaan ini, jadi itu termasuk kode Anda. Anda mungkin tertarik untuk melihat hasil pengaturan waktunya.timeit
koleksi saya .Perhatikan bahwa jawaban Geoffrey Irving salah.
Ambil urutan {3, 2, 1} sebagai contoh. Ada tiga inversi: (3, 2), (3, 1), (2, 1), jadi bilangan inversinya adalah 3. Namun, menurut metode yang dikutip jawabannya adalah 2.
sumber
Lihat ini: http://www.cs.jhu.edu/~xfliu/600.363_F03/hw_solution/solution1.pdf
Saya berharap ini akan memberi Anda jawaban yang benar.
sumber
Berikut adalah salah satu solusi yang mungkin dengan variasi pohon biner. Ia menambahkan bidang yang disebut rightSubTreeSize ke setiap simpul pohon. Terus masukkan angka ke dalam pohon biner sesuai urutan kemunculannya dalam larik. Jika number pergi lhs node, jumlah inversi untuk elemen itu akan menjadi (1 + rightSubTreeSize). Karena semua elemen itu lebih besar dari elemen saat ini dan mereka akan muncul lebih awal dalam array. Jika elemen pergi ke rhs dari sebuah node, cukup tingkatkan rightSubTreeSize-nya. Berikut adalah kodenya.
sumber
if(p->data < q->data)
duplikat tidak ditangani dengan benar. Dan tidak perlu mengujiq
di bagian atas loop,while
loop tanpa syarat berfungsi dengan baik. Juga, Anda lalai menyebutkan bahasa apa ini. :) Dan fungsi Anda tampaknya telah kehilangan baris header-nya.sumber
Karena ini adalah pertanyaan lama, saya akan memberikan jawaban saya dalam C.
sumber
Berikut adalah solusi c ++
sumber
Jawaban ini berisi hasil
timeit
tes yang dihasilkan oleh kode di jawaban utama saya . Silakan lihat jawaban itu untuk detailnya!sumber
Berikut adalah kode C untuk menghitung inversi
Penjelasan diberikan secara rinci di sini: http://www.geeksforgeeks.org/counting-inversions/
sumber
O (n log n) waktu, O (n) solusi ruang di java.
Sebuah mergesort, dengan tweak untuk mempertahankan jumlah inversi yang dilakukan selama langkah penggabungan. (untuk mergesort yang dijelaskan dengan baik lihat di http://www.vogella.com/tutorials/JavaAlgorithmsMergesort/article.html )
Karena penggabungan dapat dilakukan di tempat, kompleksitas ruang dapat ditingkatkan menjadi O (1).
Saat menggunakan pengurutan ini, inversi hanya terjadi pada langkah penggabungan dan hanya jika kita harus meletakkan elemen dari bagian kedua sebelum elemen dari paruh pertama, misalnya
digabung dengan
kami memiliki 3 + 2 + 0 = 5 inversi:
Setelah kita membuat 5 inversi, daftar gabungan kita yang baru adalah 0, 1, 5, 6, 10, 15, 22
Ada tugas demo di Codility yang disebut ArrayInversionCount, di mana Anda dapat menguji solusi Anda.
sumber
Berikut adalah implementasi perl O (n * log (n)):
sumber
Jawaban saya dengan Python:
1- Urutkan Array terlebih dahulu dan buat salinannya. Dalam program saya, B mewakili array yang diurutkan. 2- Iterasi di atas larik asli (tidak diurutkan), dan temukan indeks elemen itu pada daftar yang diurutkan. Catat juga indeks elemen. 3- Pastikan elemen tidak memiliki duplikat, jika memiliki maka Anda perlu mengubah nilai indeks Anda dengan -1. Kondisi sementara di program saya persis seperti itu. 4- Terus hitung inversi yang akan menjadi nilai indeks Anda, dan hapus elemen setelah Anda menghitung inversinya.
sumber
timeit
perbandingan dari semua jawaban Python untuk pertanyaan ini, jadi itu termasuk kode Anda. Anda mungkin tertarik untuk melihat hasil pengaturan waktunya.Saya memiliki solusi yang berbeda tetapi saya khawatir itu hanya akan berfungsi untuk elemen array yang berbeda.
Untuk menjelaskan kode saya, kami terus menambahkan elemen dari akhir Array. Untuk setiap elemen array yang masuk, kami menemukan indeks elemen pertama dalam vektor v yang lebih besar dari elemen yang masuk dan menetapkan nilai itu ke hitungan inversi dari indeks elemen yang masuk Setelah itu kita masukkan elemen tersebut ke dalam vektor v pada posisi yang benar sehingga vektor v tetap dalam urutan yang terurut.
sumber
Solusi Python lain, yang singkat. Memanfaatkan modul bisect builtin, yang menyediakan fungsi untuk memasukkan elemen ke tempatnya dalam array terurut dan untuk menemukan indeks elemen dalam array terurut.
Idenya adalah untuk menyimpan elemen yang tersisa dari n-th dalam larik tersebut, yang akan memungkinkan kita untuk dengan mudah menemukan jumlah mereka yang lebih besar dari n-th.
sumber
timeit
perbandingan dari semua jawaban Python untuk pertanyaan ini, jadi itu termasuk kode Anda. Anda mungkin tertarik untuk melihat hasil pengaturan waktunya. : DJawaban mudah O (n ^ 2) adalah dengan menggunakan for-loop bersarang dan menambah penghitung untuk setiap inversi
Sekarang saya kira Anda menginginkan solusi yang lebih efisien, saya akan memikirkannya.
sumber
Salah satu solusi yang mungkin dalam C ++ memenuhi persyaratan kompleksitas waktu O (N * log (N)) adalah sebagai berikut.
Ini berbeda dari jenis gabungan biasa hanya dengan penghitung.
sumber
Inilah solusi O (n log n) saya di Ruby:
Dan beberapa kasus uji:
sumber
Cara terbaik yang dioptimalkan adalah menyelesaikannya melalui merge sort di mana akan menggabungkan dirinya sendiri, kita dapat memeriksa berapa banyak inversi yang diperlukan dengan membandingkan array kiri dan kanan. Setiap elemen pada array kiri lebih besar dari elemen pada array kanan, maka akan terjadi inversi.
Gabungkan Pendekatan sortir: -
Ini kodenya. Kode sama persis dengan jenis gabungan kecuali potongan kode di bawah
mergeToParent
metode di mana saya menghitung inversi di bawah kondisi lain(left[leftunPicked] < right[rightunPicked])
Pendekatan lain dimana kita dapat membandingkan array input dengan array yang diurutkan: - Implementasi jawaban Diablo ini. Meskipun ini seharusnya tidak menjadi pendekatan yang disukai karena menghapus n elemen dari larik atau daftar adalah log (n ^ 2).
sumber
Jumlah maksimum inversi yang mungkin untuk daftar ukuran
n
dapat digeneralisasikan dengan ekspresi:Jadi untuk sebuah array dengan ukuran
6
inversi maksimum yang mungkin akan sama15
.Untuk mencapai kerumitan,
n logn
kita dapat mendukung algoritme inversi pada merge sort.Berikut adalah langkah-langkah umum:
inversionCount += leftSubArray.length
Itu dia!
Ini contoh sederhana yang saya buat dengan Javascript:
sumber
Implementasi menghitung inversi dalam array dengan merge sort di Swift:
Perhatikan bahwa jumlah swap bertambah
(yang merupakan panjang relatif dari sisi kiri larik dikurangi indeks elemen saat ini di sisi kiri)
... karena itu adalah jumlah elemen yang harus dilewati elemen di sisi kanan array (# inversi) untuk diurutkan.
sumber
Sebagian besar jawaban didasarkan pada
MergeSort
tetapi ini bukan satu-satunya cara untuk menyelesaikannyaO(nlogn)
Saya akan membahas beberapa pendekatan.
Gunakan
Balanced Binary Search Tree
Sesuatu seperti ini.
Binary Indexed Tree
Segment Tree
[0, a[i]-1]
dan perbaruia[i] with 1
Juga, saat menggunakan
BIT
atauSegment-Tree
ide bagus adalah melakukannyaCoordinate compression
sumber
C ++ Θ (n lg n) Solusi dengan pencetakan pasangan yang merupakan hitungan inversi.
sumber
Gunakan mergesort, dalam penghitung incremeant langkah gabungan jika nomor yang disalin ke output berasal dari larik kanan.
sumber
Saya baru-baru ini harus melakukan ini di R:
sumber