อัลกอริธึมการตรวจจับรอบของฟลอยด์ การกำหนดจุดเริ่มต้นของวงจร


32

ฉันต้องการความช่วยเหลือในการทำความเข้าใจอัลกอริธึมการตรวจจับรอบของฟลอยด์ ฉันได้อธิบายเกี่ยวกับ wikipedia ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare แล้ว )

ฉันสามารถดูว่าอัลกอริทึมตรวจจับรอบในเวลา O (n) อย่างไรก็ตามฉันไม่สามารถมองเห็นความจริงที่ว่าเมื่อเต่าและกระต่ายมาพบกันเป็นครั้งแรกการเริ่มต้นของวงจรสามารถถูกกำหนดได้โดยการเลื่อนตัวชี้ของเต่ากลับไปที่จุดเริ่มต้นแล้วขยับทั้งเต่าและกระต่ายทีละขั้น จุดที่พวกเขาพบกันครั้งแรกคือจุดเริ่มต้นของวงจร

ใครช่วยได้โดยให้คำอธิบายหวังว่าจะแตกต่างจากวิกิพีเดียเพราะฉันไม่สามารถเข้าใจ / เห็นภาพได้


3
ฉันพบคำตอบใน stackoverflow ขอบคุณถ้ามีคนกำลังมองหาสิ่งนี้สำหรับฉัน และสำหรับคนที่ชอบฉันต้องการคำอธิบายโปรดอ้างถึง: stackoverflow.com/questions/3952805/… คำตอบที่เลือกสำหรับคำถามอธิบายมัน!
Anurag Kapur

สวัสดี @Anurag สำหรับข้อมูลของคุณฉันได้โพสต์บล็อกในอัลกอริทึม "Tortoise and the Hare" ที่นี่
Kyle

คุณรู้หรือไม่ว่าทำไมfastตัวแปรหรือ "กระต่าย" จึงต้องการความเร็วเป็นสองเท่าของเต่าแทนที่จะเป็นแค่ข้างเดียว?
devdropper87

อธิบายอย่างดีกับโปรแกรม: javabypatel.blogspot.in/2015/12/detect-loop-in-linked-list.html
Jayesh

คำตอบ:


47

คุณสามารถอ้างถึง"การตรวจจับจุดเริ่มต้นของลูปในรายการที่เชื่อมโยงโดยลำพัง"นี่เป็นข้อความที่ตัดตอนมา:

ป้อนคำอธิบายรูปภาพที่นี่

ระยะทางเดินทางโดยslowPointerก่อนการประชุม =x+y

fastPointer =(x+y+z)+y = x + 2y + z

เนื่องจากการfastPointerเดินทางด้วยความเร็วเป็นสองเท่าของslowPointerและเวลาคงที่สำหรับทั้งสองเมื่อถึงจุดนัดพบ ดังนั้นโดยใช้ความสัมพันธ์ระหว่างความเร็วเวลาและระยะทางที่ง่าย ( slowPointerเดินทางครึ่งระยะทาง):

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

ดังนั้นโดยการย้ายslowPointerไปยังจุดเริ่มต้นของรายการที่เชื่อมโยงและทำให้ทั้งสองslowPointerและfastPointerจะย้ายโหนดหนึ่งในเวลาที่พวกเขาทั้งสองมีระยะทางเดียวกันกับปก

พวกเขาจะไปถึงจุดที่ลูปเริ่มต้นในรายการที่เชื่อมโยง


2
ที่นี่คุณได้ตั้งสมมติฐานว่าพวกเขาจะได้พบกันหลังจากการหมุนครั้งเดียว อาจมีกรณี (ที่รอบมีขนาดเล็ก) ที่พวกเขาอาจพบหลังจากไม่แน่นอน ของการหมุน
Navjot Waraich

1
@JotWaraich รูปภาพไม่ได้เป็นตัวแทนของทุกกรณี ตรรกะยังคงถือ
denis631

3
นี่เป็นคำตอบที่ตรงไปตรงมาที่สุดเกี่ยวกับอัลกอริทึมนี้ในอินเทอร์เน็ตทั้งหมด
Marshall X

7

ฉันได้เห็นคำตอบที่ยอมรับว่าเป็นข้อพิสูจน์ที่อื่นด้วย อย่างไรก็ตามในขณะที่ง่ายต่อการ grok มันไม่ถูกต้อง สิ่งที่พิสูจน์ได้คือ

x=z (ซึ่งเห็นได้ชัดว่าผิดและไดอะแกรมทำให้ดูเหมือนเป็นไปได้เนื่องจากวิธีร่างภาพ)

สิ่งที่คุณต้องการพิสูจน์คือ (ใช้ตัวแปรเดียวกับที่อธิบายไว้ในแผนภาพในคำตอบที่ยอมรับด้านบน):

z=x mod (y+z)

(y+z)L

ดังนั้นสิ่งที่เราต้องการพิสูจน์คือ:

z=x mod L

หรือว่า z สอดคล้องกับ x (โมดูโล L)

หลักฐานต่อไปนี้ทำให้รู้สึกถึงฉันมากขึ้น:

M=x+y

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

x+y=kL

x=kLy

xLyMx+y


0

ฉันพบคำตอบใน stackoverflow ขอบคุณถ้ามีคนกำลังมองหาสิ่งนี้สำหรับฉัน และสำหรับผู้ที่ชอบฉันต้องการคำอธิบายโปรดดูที่: https://stackoverflow.com/questions/3952805/proof-of-detecting-the-start-of-cycle-in-linked-listคำตอบที่เลือกไปยัง คำถามอธิบายมัน!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.