Baru-baru ini, saya menemukan masalah klasik untuk wawancara: mencari jumlah maksimum poin berdiri di garis lurus (di pesawat, bilangan bulat koordinat). Gagasan pencarian lengkap segera muncul di benak saya, yang memiliki kompleksitas waktu yang jelas dalam O (n ^ 2), tetapi bagi saya tampaknya ada sesuatu yang lain, setidaknya beberapa alternatif dalam O (n * log (n)) . Setelah setengah jam, bahkan sesuatu yang lebih baik ditemukan!
Pernyataan masalah yang lebih terperinci dengan contoh input-output ada di GeeksForGeeks dan LeetCodePada awalnya saya perhatikan bahwa Anda dapat dengan mudah menyelesaikan masalah hanya untuk garis horizontal atau vertikal, menambahkan X / Y dari setiap titik dalam kamus. Dan bagaimana perbedaan jalur lainnya? Hanya lereng? .. Tapi ini bisa diperbaiki!
Jadi, saya memutuskan bahwa mungkin untuk memeriksa seluruh daftar poin beberapa kali dengan memutarnya. Dan solusi dalam O (n) diperoleh! Meskipun dengan koefisien yang besar. Saya sangat berharap bahwa saya tidak menciptakan sepeda :)
Divisualisasikan, tampilannya seperti ini:
GIF buatan saya yang pertama, jangan dimarahi :)
Sangat menarik untuk dicatat bahwa
implementasi selanjutnya
dari pencarian lengkap mengambil lebih banyak baris kode.
Grafik dengan pengukuran runtime dari algoritma rotasi saya dan penghitungan lengkap tergantung pada jumlah poin di header.
Sekitar 150 poin menunjukkan keunggulan kompleksitas linier dalam waktu (dengan koefisien yang digunakan dalam kode di atas). Alhasil, algoritma ini memiliki kelemahan sebagai berikut:
- Akurasinya tidak absolut.
- Runtime pada set poin kecil itu panjang.
Secara umum, ini mudah dikoreksi dengan pemilihan koefisien yang kompeten: untuk set sederhana, ROT_COUNT = 36 daripada 2000 sudah cukup, yang mempercepat kode 50+ kali.
Dan keuntungan seperti itu:
- Ini bekerja dengan tenang dengan koordinat fraksional.
- Kompleksitas waktu linear, yang terlihat pada set data besar.
Tabel dengan pengukuran
tersedia di sini . Seluruh kode sumber proyek dengan algoritma dan berbagai pemeriksaan
ada di GitHub .
Perbarui Saya ingin sekali lagi mencatat bahwa algoritma ini memiliki kelebihan dan kekurangan, saya tidak menganjurkannya sebagai pengganti yang ideal untuk brute force, saya hanya menggambarkan alternatif yang mungkin menarik, yang dalam beberapa kasus mungkin lebih tepat.