Algoritma deteksi siklus Floyd | Menentukan titik awal siklus


32

Saya mencari bantuan untuk memahami algoritma pendeteksian siklus Floyd. Saya telah membaca penjelasan di wikipedia ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Saya dapat melihat bagaimana algoritma mendeteksi siklus dalam waktu O (n). Namun, saya tidak dapat memvisualisasikan fakta bahwa setelah kura-kura dan kelinci bertemu untuk pertama kalinya, permulaan siklus dapat ditentukan dengan menggerakkan penunjuk kura-kura kembali untuk memulai dan kemudian memindahkan kura-kura dan kelinci satu langkah pada satu waktu. Titik pertemuan pertama mereka adalah awal siklus.

Dapatkah seseorang membantu dengan memberikan penjelasan, semoga berbeda dari yang ada di wikipedia, karena saya tidak dapat memahami / memvisualisasikannya?


3
Saya menemukan jawabannya di stackoverflow. Terima kasih jika ada yang mencari ini untuk saya. Dan bagi mereka yang menyukai saya ingin penjelasan, silakan merujuk ke: stackoverflow.com/questions/3952805/… Jawaban yang dipilih untuk pertanyaan itu, jelaskan!
Anurag Kapur

Hai @Anagag. Sekadar informasi Anda, saya sudah melakukan posting blog pada algoritma "Tortoise and the Hare" di sini
Kyle

Apakah Anda tahu mengapa fastvariabel, atau "kelinci" perlu bergerak dua kali lebih cepat dari kura-kura, bukan hanya satu di depan?
devdropper87

Jawaban:


47

Anda dapat merujuk ke "Mendeteksi awal loop dalam daftar yang ditautkan sendiri" , berikut adalah kutipannya:

masukkan deskripsi gambar di sini

Jarak yang ditempuh slowPointersebelum pertemuan =x+y

fastPointer =(x+y+z)+y

Karena fastPointerperjalanan dengan kecepatan dua kali lipatslowPointer , dan waktu adalah konstan untuk keduanya ketika mencapai titik pertemuan. Jadi dengan menggunakan hubungan kecepatan, waktu dan jarak yang sederhana ( slowPointermenempuh setengah jarak):

2dist(slowPointer)=dist(fastPointer)2(x+y)=x+2y+z2x+2y=x+2y+zx=z

Oleh karena itu dengan bergerak slowPointeruntuk memulai daftar tertaut, dan membuat keduanya slowPointerdan fastPointeruntuk memindahkan satu simpul pada satu waktu, mereka berdua memiliki jarak yang sama untuk menutupi .

Mereka akan mencapai pada titik di mana loop dimulai pada daftar yang ditautkan.


2
Di sini Anda telah membuat asumsi bahwa mereka akan bertemu setelah satu putaran. Mungkin ada kasus (di mana siklusnya kecil) di mana mereka mungkin bertemu setelah no tertentu. rotasi.
Navjot Waraich

1
@JotWaraich gambar tidak mewakili semua kasus; Namun logikanya masih berlaku
denis631

3
ini adalah jawaban paling langsung tentang algoritma ini di seluruh Internet
Marshall X

7

Saya telah melihat jawaban yang diterima sebagai bukti di tempat lain juga. Namun, meskipun mudah untuk grok, itu tidak benar. Apa buktinya

x=z

Apa yang benar-benar ingin Anda buktikan adalah (menggunakan variabel yang sama seperti yang dijelaskan dalam diagram pada jawaban yang diterima di atas):

z=x mod (y+z)

(y+z)L

jadi, yang ingin kita buktikan adalah:

z=x mod L

Atau z itu kongruen dengan x (modulo L)

Bukti berikut lebih masuk akal bagi saya:

M=x+y

2(x+y)=M+kLkx+yL

x+y=kL

x=kLy

xLyMx+y


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.