Tulis sebuah program (atau fungsi) yang memperlihatkan empat kompleksitas waktu O besar yang umum tergantung pada cara dijalankannya. Dalam bentuk apa pun yang diperlukan dalam bilangan bulat N positif yang Anda anggap kurang dari 31 .
Ketika program dijalankan dalam bentuk aslinya , ia harus memiliki kompleksitas konstan . Yaitu, kompleksitasnya harus Θ (1) atau, dengan kata lain, Θ (1 ^ N) .
Ketika program dibalik dan dijalankan harus memiliki kompleksitas linier . Artinya, kompleksitasnya harus Θ (N) atau, ekuivalen, Θ (N ^ 1) .
(Ini masuk akal karenaN^1
yang1^N
terbalik.)Ketika program ini dua kali lipat , yaitu concatenated untuk dirinya sendiri, dan menjalankannya harus memiliki eksponensial kompleksitas, khususnya 2 N . Artinya, kompleksitasnya harus Θ (2 ^ N) .
(Ini masuk akal karena2
in2^N
adalah double1
in1^N
.)Ketika program digandakan dan dibalik dan dijalankan harus memiliki kompleksitas polinomial , khususnya N 2 . Artinya, kompleksitasnya harus Θ (N ^ 2) .
(Ini masuk akal karenaN^2
yang2^N
terbalik.)
Keempat kasus ini adalah satu-satunya yang perlu Anda tangani.
Perhatikan bahwa untuk ketepatan saya menggunakan notasi theta (Θ) besar alih-alih O besar karena runtime program Anda harus dibatasi baik di atas maupun di bawah oleh kompleksitas yang diperlukan. Kalau tidak, hanya menulis fungsi dalam O (1) akan memenuhi keempat poin. Tidak terlalu penting untuk memahami nuansa di sini. Terutama, jika program Anda melakukan operasi k * f (N) untuk beberapa konstanta k maka kemungkinan dalam Θ (f (N)).
Contoh
Jika program aslinya
ABCDE
maka menjalankannya akan membutuhkan waktu yang konstan. Yaitu, apakah input N adalah 1 atau 2147483647 (2 31 -1) atau nilai apa pun di antaranya, ia harus diakhiri dalam jumlah waktu yang kira-kira sama.
Versi program yang dibalik
EDCBA
harus mengambil waktu linier dalam hal N. Artinya, waktu yang dibutuhkan untuk mengakhiri harus sebanding dengan N. Jadi N = 1 membutuhkan waktu paling sedikit dan N = 2147483647 mengambil paling banyak.
Versi program yang berlipat ganda
ABCDEABCDE
harus mengambil dua-to-the-N waktu dalam hal N. Artinya, waktu yang dibutuhkan untuk mengakhiri harus kira-kira sebanding dengan 2 N . Jadi jika N = 1 berakhir dalam waktu sekitar satu detik, N = 60 akan membutuhkan waktu lebih lama dari umur alam semesta untuk berakhir. (Tidak, kamu tidak perlu mengujinya.)
Versi program yang berlipat dan terbalik
EDCBAEDCBA
harus mengambil waktu kuadrat dalam hal N. Artinya, waktu yang diperlukan untuk mengakhiri harus sebanding dengan N * N. Jadi jika N = 1 berakhir dalam sekitar satu detik, N = 60 akan memakan waktu sekitar satu jam untuk berakhir.
Detail
Anda perlu menunjukkan atau berargumen bahwa program Anda berjalan dalam kompleksitas yang Anda katakan demikian. Memberikan beberapa data waktu adalah ide yang baik tetapi juga mencoba menjelaskan mengapa secara teoritis kerumitannya benar.
Tidak apa-apa jika dalam praktiknya waktu yang diambil program Anda tidak sepenuhnya mewakili kompleksitasnya (atau bahkan deterministik). mis. input N +1 mungkin terkadang berjalan lebih cepat dari N.
Lingkungan tempat Anda menjalankan program tidak masalah. Anda dapat membuat asumsi dasar tentang bagaimana bahasa populer tidak pernah secara sengaja membuang waktu dalam algoritme tetapi, misalnya, jika Anda tahu versi Java Anda mengimplementasikan bubble sort daripada algoritma penyortiran yang lebih cepat , maka Anda harus memperhitungkannya jika Anda melakukan penyortiran .
Untuk semua kompleksitas di sini asumsikan kita berbicara tentang skenario terburuk , bukan yang terbaik atau rata-rata.
Kompleksitas ruang program tidak masalah, hanya kompleksitas waktu.
Program dapat menghasilkan apa saja. Yang penting mereka mengambil bilangan bulat positif N dan memiliki kompleksitas waktu yang tepat.
Komentar dan program multiline diizinkan. (Anda dapat menganggap
\r\n
terbalik\r\n
untuk kompatibilitas Windows.)
Pengingat O Besar
Dari tercepat ke paling lambat itu O(1), O(N), O(N^2), O(2^N)
(urutan 1, 2, 4, 3 di atas).
Istilah yang lebih lambat selalu mendominasi, mis O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
untuk konstanta k. Jadi O(2) = O(30) = O(1)
dan O(2*N) = O(0.1*N) = O(N)
.
Ingat O(N^2) != O(N^3)
dan O(2^N) != O(3^N)
.
Lembar contekan O yang besar dan rapi.
Mencetak gol
Ini adalah kode golf normal. Program asli terpendek (waktu konstan) dalam byte menang.
n = input(); for i in xrange(n): pass
memiliki kompleksitas eksponensial, karena dibutuhkan 2 ** k
langkah - langkah, di mana k = log_2(n)
ukuran inputnya. Anda harus mengklarifikasi apakah ini masalahnya, karena secara dramatis mengubah persyaratan.