Menemukan jumlah elemen yang lebih kecil untuk setiap elemen dalam array secara efisien


9

Saya terjebak pada masalah ini:

Diberikan larik dari asli pertama yang diijinkan secara acak, larik dibangun, sehingga adalah jumlah elemen dari hingga yang lebih kecil dari . AnBB(k)A(1)A(k1)A(k)

i) Mengingat bisakah Anda menemukan dalam waktu ? ii) Mengingat dapatkah Anda menemukan dalam waktu ?ABO(n)
BAO(n)

Di sini, . Untuk contoh konkret: B(1)=0

|A843172965B000031644|

Ada yang bisa bantu saya? Terima kasih.


Saya menemukan ini: Komputasi encoding permutasi yang memberikan algoritma untuk masalah ini. Setidaknya saya pikir mereka adalah masalah yang sama. O(nlogn)
Realz Slaw

@Merbs apakah itu Petunjuk yang Anda berikan berarti Anda punya solusi?
AJed

1
@ AJed, itu berarti saya memiliki algoritma, meskipun dibutuhkan untuk algoritma sederhana tanpa spasi dan jika kita diizinkan ruang. Saat ini, saya condong ke arah yang tidak mungkin di dan keduanya menjadi algoritma yang sama. O ( n log n ) O ( n )O(n2)O(nlogn)O(n)
Merbs

@Merbs. Saya merasa petunjuk Anda dapat mengarah ke jalur yang benar. Saya punya satu solusi juga (mengikuti petunjuk Anda). Saya kira ada trik dalam analisis yang membuatnya menjadi .. Saya pikir triknya adalah pengetahuan bahwa beranjak dari 1: saja. A nO(n)An
AJed

2
Makalah ini juga memberikan algoritma . Apakah Anda yakin ada algoritma untuk ini? O ( n )O(nlogn)O(n)
Realz Slaw

Jawaban:


1

Algoritma naif untuk menentukan dari :ABA

Untuk , tentukan nilai dengan membandingkan setiap dengan untuk dan menghitung yang memenuhi .B ( k ) A ( i ) A ( k ) i = 1 , , k A ( i ) < A ( k )k=1,,nB(k)A(i)A(k)i=1,,kA(i)<A(k)

Algoritma ini membandingkan dengan yang lainnya ( kali), hingga lainnya, dll. Sehingga jumlah total perbandingan adalah . Tapi itu bukan yang terbaik yang bisa kita lakukan. Sebagai contoh, melihat , kita tidak perlu melakukan perbandingan! karena ini adalah alami pertama , dan dijamin (terlepas dari permutasi) bahwa bilangan alami lebih rendah akan ada di sana. Bagaimana dengan ? Alih-alih memeriksa hingga , kita bisa memeriksa . Itu adalah:A(1)n1A(2)n2(n1)(n2)2B(n)B(n)=A(n)1 nn1B(n1)A(1)A(n2)A(n)

Untuk , gunakan algoritma di atas; untuk gunakan algoritma terbalik: tentukan dengan mengaturnya awalnya ke dan kemudian kurangi untuk setiap entri untuk yang kurang dari .k=1,,n2k=n2,,nB(k)A(n)11A(i)i=k+1,,nA(k)

Ini akan memakan waktu langkah, yang masih . Perhatikan juga bahwa dalam membangun dari , jika maka .2×(n21)(n22)2=(n2)(n4)4O(n2)ABB(n)=A(n)1A(n)=B(n)+1

Tapi sekarang untuk lebih pintar. Jika kami diizinkan ruang tambahan atau mengurutkan di tempat, kami dapat mengurutkan angka saat kami membandingkannya. Sebagai contoh:

|A843172965S987432165B0000316|

Alih-alih memeriksa semuanya (atau memeriksanya secara berurutan), kita bisa menggunakan pencarian biner untuk menentukan masing-masing . Namun, pengurutan masih membutuhkan waktu .B(k)O(nlogn)


Ini hanya ide pertamaku; meskipun saya menyadari masalahnya lebih menarik daripada awalnya saya memberikannya kredit. Dan saya belum memiliki kesempatan untuk membaca temuan Realz Slaw, jadi algoritmenya mungkin tidak aktif.
Merbs

0

Daripada menentukan masing-masing satu per satu, kita bisa melihat ke depan dan hanya melewati setiap angka dalam sekali ! Tapi kami akan menggunakan ruang :B(k)A n

|A123456789B800000000104000011112030001222230101123333407011233345320123444561901234445666012344567450123456784|

Kami dapat menghemat lebih banyak waktu dengan tidak memperbarui yang sudah ditentukan (yaitu, tidak ada gunanya memperbarui setelah langkah pertama), tetapi dalam kasus terburuk, kami masih harus memperbarui kali8(n)(n+2)2


0

I dan II dapat dipecahkan menggunakan #next_greater_element yang saya jelaskan di sini . tetapi ini sedikit lebih sulit daripada hanya masalah tetapi sebelum solusi Anda perlu mempelajari elemen selanjutnya yang lebih besar:

  1. anggap kita memiliki vektor untuk setiap elemen name it for element . sekarang setelah menjalankan algoritma yang lebih besar berikutnya mulai dari kanan ke kiri tetapi kecuali pengaturan elemen di indeks elemen berikutnya yang lebih besar, dorong elemen yang adalah elemen lebih besar berikutnya. Kemudian beralih ke array kiri ke kanan dan kemudian mana adalah ukuran vektor .dan itu karena masing-masing algoritma yang lebih besar berikutnya adalah dan juga iterasi adalahASiiiASiiB[i]=j=0x(Si[j]+1)xSiΘ(n)Θ(n)Θ(n)

Bagian kedua juga mirip dengan catatan bahwa kita bisa mendapatkan nilai elemen yang paling tepat di EDIT: solusi saya salah sepertinya tidak ada solusio ( n )O(1)o(n)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.