อธิบายว่าการค้นหาโหนดเริ่มรอบในการเชื่อมโยงรายการทำงานอย่างไร


161

ฉันเข้าใจว่าการประชุมของ Tortoise และ Hare สรุปว่าการมีอยู่ของวงวนนั้นเป็นอย่างไร แต่การย้ายเต่าไปยังจุดเริ่มต้นของรายการที่เชื่อมโยงในขณะที่รักษากระต่าย ณ สถานที่ประชุมตามด้วยการย้ายทั้งสองขั้นในแต่ละครั้ง


คำอธิบายอื่น ๆ : marcin-chwedczuk.github.io/ …
csharpfolk

ผู้คนยังไม่ใส่ใจที่จะดูเกินสองคำตอบแรกสำหรับคำถามนี้ คำตอบที่สามค่อนข้างดี
displayName

คำตอบ:


80

นี่คือขั้นตอนวิธีการของฟลอยด์สำหรับการตรวจสอบวงจร คุณกำลังถามเกี่ยวกับขั้นตอนที่สองของอัลกอริทึม - เมื่อคุณพบโหนดที่เป็นส่วนหนึ่งของวัฏจักรแล้วจะพบจุดเริ่มต้นของรอบได้อย่างไร

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

เมื่อเต่าและกระต่ายตอบสนองเราได้พบฉันที่เล็กที่สุด (จำนวนของขั้นตอนการดำเนินการโดยเต่าที่) เช่นว่า X ฉัน x = 2i ให้ mu แทนจำนวนขั้นตอนที่จะได้รับจาก X 0ถึงจุดเริ่มต้นของรอบและให้แลมบ์ดาแสดงความยาวของรอบ จากนั้น i = mu + a แลมบ์ดาและ 2i = mu + bแลมบ์ดาโดยที่ a และ b เป็นจำนวนเต็มแสดงถึงจำนวนเต่าและกระต่ายเดินไปรอบ ๆ กี่ครั้ง การลบสมการแรกจากสมการที่สองให้ i = (ba) * แลมบ์ดาดังนั้นฉันจึงเป็นจำนวนเต็มหลายแลมบ์ดา ดังนั้น X i + MU = Xหมู่ X iหมายถึงจุดนัดพบของเต่าและกระต่าย หากคุณย้ายเต่ากลับไปที่โหนดเริ่มต้น X0และปล่อยให้เต่าและกระต่ายดำเนินต่อไปด้วยความเร็วเดียวกันหลังจาก mu ขั้นตอนเพิ่มเติมเต่าจะมาถึง X muและกระต่ายจะมาถึง X i + mu = X muดังนั้นจุดนัดพบที่สองจึงเป็นจุดเริ่มต้นของ วงจร


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

6
@Jim Lewis มันคงจะดีมากถ้าคุณสามารถอธิบายได้ว่าการให้ i เป็นผลคูณความยาวของลูปเป็น mu เป็นระยะทางระหว่างจุดนัดพบครั้งแรกและการเริ่มต้นลูป
โปรแกรมเมอร์ที่หลงใหล

7
@Passionate: ทำตามขั้นตอน mu จากจุดเริ่มต้นเพื่อไปยังจุดX_muเริ่มต้นของรอบ (ตามคำนิยามของ mu) แล้วถ้าคุณใช้เวลาฉันขั้นตอนอื่น ๆ อีกมากมายที่ฉันมีหลายความยาวรอบที่คุณจะจบลงกลับมาที่จุดเริ่มต้นวงจร: =X_mu + i X_muแต่การเพิ่มเป็นแบบสับเปลี่ยนดังนั้นนี่เทียบเท่ากับการทำตามขั้นตอน i เพื่อรับตั้งแต่จุดเริ่มต้นจนถึงจุดนัดพบครั้งแรกX_iจากนั้นขั้นตอนเพิ่มเติมเพื่อกลับไปสู่X_muจุดเริ่มต้นของรอบ
Jim Lewis

2
@ankur: จุดนัดพบคือ X_i และเราได้แสดง (ย่อหน้าที่สามในคำตอบของฉัน) ว่าฉันจะต้องมีความยาวหลายรอบ หลังจาก mu ขั้นตอนเพิ่มเติมผ่านจุดนัดพบคุณอยู่ที่ X_ (i + mu) แต่เราได้แสดงให้เห็นแล้วว่า X_ (i + mu) = X_ (mu + i) = X_mu เนื่องจากคุณสมบัติพิเศษของ i ดังนั้น mu ขั้นตอนที่ผ่านจุดนัดพบจะต้องนำคุณไปที่ X_mu ซึ่งเป็นจุดเริ่มต้นของวัฏจักร เลขคณิตพื้นฐานแบบแยกส่วนบวกกับคุณสมบัติการสับเปลี่ยนของการเพิ่ม
Jim Lewis

28
ฉันคิดว่ามีปัญหาเล็กน้อยในการพิสูจน์ของคุณ ตั้งแต่จุดนัดพบiคือในบางจุดของวงจรผมคิดว่าสมการที่ควรจะเป็นi = mu + k + a*lambdaและ2i = mu + k + b*lambdaที่kคือจำนวนของขั้นตอนตั้งแต่เริ่มต้นวงจรไปยังจุดที่ประชุม การลบสมการทั้งสองจะให้ผลลัพธ์เหมือนกัน
Ivan Z. Siu

336

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

การวาดภาพ

มันทำงานอย่างไร

ให้เต่าและกระต่าย (ชื่อพอยน์เตอร์) ชี้ไปที่จุดเริ่มต้นของรายการด้วยวงจรเช่นเดียวกับในแผนภาพด้านบน

สมมุติว่าถ้าเราย้ายเต่าไปทีละขั้นตอนละหนึ่งก้าวและในอีกสองขั้นตอนพวกมันจะพบกันทีละจุด ขอแสดงให้เห็นว่าสมมติฐานข้อแรกทั้งหมดนี้เป็นจริง

ภาพแสดงรายการที่มีวงจร วงจรมีความยาวnและเราอยู่mห่างจากรอบแรก สมมติว่าจุดนัดพบนั้นอยู่kห่างจากจุดเริ่มต้นของวงจรและเต่าและกระต่ายก็พบกันเมื่อเต่าทำiตามขั้นตอนทั้งหมดแล้ว (กระต่ายจะต้องทำ2iตามขั้นตอนทั้งหมดแล้ว)

เงื่อนไข 2 ข้อต่อไปนี้ต้องถือไว้:

1) i = m + p * n + k

2) 2i = m + q * n + k

คนแรกบอกว่าเต่าเคลื่อนที่iตามขั้นตอนและในiขั้นตอนเหล่านี้มันจะเข้าสู่รอบแรก จากนั้นก็จะไปผ่านวงจรครั้งสำหรับจำนวนบวกบางp pในที่สุดมันจะไปยังkโหนดอื่น ๆ จนพบกับกระต่าย

ที่คล้ายกันเป็นจริงสำหรับกระต่าย มันเคลื่อนที่2iตามขั้นตอนและใน2iขั้นตอนเหล่านี้ก่อนที่จะถึงรอบ จากนั้นก็จะไปผ่านวงจรครั้งสำหรับจำนวนบวกบางq qในที่สุดมันจะไปยังkโหนดอื่น ๆ จนกระทั่งพบกับเต่า

เมื่อกระต่ายเดินทางด้วยความเร็วเป็นสองเท่าของเต่าและเวลาก็คงที่เมื่อทั้งคู่มาถึงจุดนัดพบ

ดังนั้นโดยใช้ความสัมพันธ์ระหว่างความเร็วเวลาและระยะทางแบบง่าย ๆ

2 ( m + p * n + k ) = m + q * n + k

=> 2m + 2pn + 2k = m + nq + k 

=>  m + k = ( q - 2p ) n

ในบรรดา m, n, k, p, q สองคนแรกคือคุณสมบัติของรายการที่กำหนด หากเราสามารถแสดงให้เห็นว่ามีค่าอย่างน้อยหนึ่งชุดสำหรับ k, q, p ที่ทำให้สมการนี้เป็นจริงเราแสดงว่าสมมติฐานนั้นถูกต้อง

หนึ่งชุดโซลูชันดังกล่าวมีดังนี้:

p = 0

q = m

k = m n - m

เราสามารถตรวจสอบว่าค่าเหล่านี้ทำงานดังนี้:

m + k = ( q - 2p ) n  

=> m + mn - m = ( m - 2*0) n

=> mn = mn.

สำหรับเซตนี้iคือ

i = m + p n + k

=> m + 0 * n + mn - m = mn.

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

ตอนนี้เราสามารถไปที่ส่วนที่สองของอัลกอริทึมซึ่งเป็นวิธีหาจุดเริ่มต้นของวัฏจักร

รอบเริ่มต้น

เมื่อเต่าและกระต่ายมาพบกันให้นำเต่ากลับไปที่จุดเริ่มต้นของรายการและให้กระต่ายที่พวกเขาพบกัน (ซึ่งอยู่ห่างจากจุดเริ่มต้นของวงจร k)

สมมติฐานคือถ้าเราปล่อยให้พวกเขาเคลื่อนที่ด้วยความเร็วเดียวกัน (1 ขั้นตอนสำหรับทั้งคู่) ครั้งแรกที่พวกเขาพบกันอีกครั้งจะเป็นการเริ่มต้นรอบ

ลองพิสูจน์สมมติฐานนี้กัน

ก่อนอื่นสมมติว่า oracle บอกเราว่า m คืออะไร

จากนั้นถ้าเราปล่อยให้พวกเขาเคลื่อนที่ m + k ก้าวเต่าจะต้องมาถึงจุดที่พวกเขาพบกันในขั้นต้น (k ก้าวออกไปจากจุดเริ่มต้นของวงจร - ดูในรูป)

m + k = (q - 2p) nก่อนหน้านี้เราแสดงให้เห็นว่า

เนื่องจาก m + k ก้าวเป็นหลายรอบความยาว n, ในเวลาเฉลี่ย, จะผ่านรอบ (q-2p) ครั้งและจะกลับมาที่จุดเดียวกัน (k ก้าวออกจากจุดเริ่มต้นของรอบ)

ทีนี้แทนที่จะปล่อยให้พวกมันเคลื่อนที่ m + k ก้าวถ้าเราปล่อยให้พวกมันเคลื่อนที่เพียงแค่ก้าว m เท่านั้นเต่าจะมาถึงจุดเริ่มต้นของวงจร กระต่ายจะเป็นขั้นตอนสั้น ๆ ในการหมุน (q-2p) k เนื่องจากมันเริ่มต้น k ก้าวต่อหน้าวงรอบเริ่มต้นกระต่ายจึงต้องมาถึงจุดเริ่มต้นของวงจร

เป็นผลให้สิ่งนี้อธิบายว่าพวกเขาจะต้องพบกันที่วัฏจักรที่เริ่มต้นหลังจากขั้นตอนบางอย่างเป็นครั้งแรก (ครั้งแรกเพราะเต่าเพิ่งมาถึงรอบหลังจากขั้นตอน m และมันไม่เคยเห็นกระต่ายซึ่งอยู่ใน รอบ)

ตอนนี้เรารู้แล้วว่าจำนวนของขั้นตอนที่เราต้องย้ายพวกเขาจนกว่าพวกเขาจะพบกันกลายเป็นระยะทางจากจุดเริ่มต้นของรายการไปยังจุดเริ่มต้นของวงจรม. แน่นอนว่าอัลกอริทึมไม่จำเป็นต้องรู้ว่า m คืออะไร มันจะขยับทั้งเต่าและกระต่ายทีละก้าวจนกว่าพวกเขาจะพบกัน จุดนัดพบต้องเป็นการเริ่มรอบและจำนวนขั้นตอนต้องเป็นระยะทาง (m) ถึงจุดเริ่มต้นรอบ สมมติว่าเรารู้ความยาวของรายการเราสามารถคำนวณความยาวของวัฏจักรของการลบ m จากความยาวของรายการ


1
ฉันไม่คิดว่ามันจริงที่เมื่อพวกเขาพบว่าเป็นจุดเริ่มต้นดูความคิดเห็นด้านล่าง: stackoverflow.com/a/19209858/1744146 <br> โปรดแจ้งให้เราทราบหากฉันผิด
MrA

ส่วนแรกของคำอธิบายไร้ที่ติ แต่ส่วนที่สองมีข้อบกพร่องเท่าที่ฉันรู้ คุณกำลังสมมติว่า "oracle บางตัวบอกว่า m" แต่ถ้ารู้จัก m คุณก็มีจุดเริ่มต้นของวัฏจักรอยู่แล้ว คุณจะคาดเดาคำตอบได้อย่างไรเมื่อคุณไม่เคยรู้ว่าจุดเริ่มต้นของวัฏจักรอยู่ที่ไหน? โปรดแจ้งให้เราทราบ
Gopichand

1
@Gopichand อ่าน para สุดท้ายอีกครั้ง ... คุณแค่คิดว่ามีบาง m (ถ้าพิสูจน์แล้วว่ามีรอบ) .. แต่คุณไม่รู้ค่าของ m
Srinath

2
นี่เป็นคำอธิบายที่น่าอัศจรรย์จริงๆ นี่อาจเป็นคำอธิบายที่ดีที่สุดในปัจจุบันบนอินเทอร์เน็ตทั้งหมด
Arlene Batada

2
สมการของคุณm + k = (q - 2p) nสามารถทำให้ง่ายขึ้นไปm + k = q*nอีก นี่เป็นเพราะจำนวนของเต่าลูปจะเป็นศูนย์เสมอเพราะกระต่ายไม่สามารถแซงหน้าเต่าได้โดยไม่ต้องพบมัน ลองคิดดู
Arpit Jain

124

อ้างอิงภาพนี้:

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

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

ระยะทางเดินทางโดย fastPointer ก่อนการประชุม = (x + y + z) + y = x + 2y + z

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

ดังนั้นโดยใช้ความเร็วความสัมพันธ์ระหว่างเวลาและระยะทางที่เรียบง่าย 2 (x + y) = x + 2y + z => x + 2y + z = 2x + 2y => x = z

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

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


10
สิ่งนี้ไม่ได้คำนึงถึงกรณีที่ fastPointer เดินทางรอบ n ครั้งก่อนที่ slowPointer จะเข้าสู่รอบ ใช้ l เพื่อแสดงความยาวของรอบ ระยะทางเดินทางโดย fastPointer ก่อนการประชุม = (x + y + z) + y = x + 2y + nl + z และความสัมพันธ์ที่เกิดขึ้นจะเป็น x = nl + z
Jingguo Yao

@JingguoYao: นี่คือคำอธิบายสำหรับกรณีนั้น
displayName

2
แผนภาพนี้ง่ายเกินไป ตัวชี้แบบเร็วสามารถเคลื่อนที่ได้หลายรอบผ่านวงจรก่อนที่ตัวชี้แบบช้าจะมาถึง
Warren MacEvoy

70

คำตอบที่เรียบง่ายและต่ำกว่าต่ำของ Old Monkอธิบายการค้นหาวัฏจักรเมื่อนักวิ่งเร็วทำเพียงรอบเดียวเท่านั้น ในคำตอบนี้ฉันอธิบายกรณีเมื่อนักวิ่งเร็ววิ่งวนซ้ำหลายครั้งก่อนที่นักวิ่งช้าจะเข้าสู่วง


ใช้ภาพเดียวกัน:ป้อนคำอธิบายรูปภาพที่นี่

สมมุติว่านักวิ่งเร็ววิ่งวนรอบmก่อนที่จะเจอช้าและเร็ว ซึ่งหมายความว่า:

  • ระยะทางวิ่งช้า: x + y
  • ระยะทางวิ่งเร็ว: x + m (y + z) + yเช่น Extra yที่พวกเขาพบกัน

เนื่องจากการวิ่งที่รวดเร็วด้วยความเร็วของการช้าเป็นสองเท่าและมันวิ่งในเวลาเดียวกันนั่นก็หมายความว่าถ้าเราวิ่งเป็นสองเท่าของระยะทางที่ช้าเราจะได้ระยะทางที่เร็ว ดังนั้น

  • 2 (x + y) = x + m (y + z) + y

แก้เพื่อให้ x

x = (m - 1) (y + z) + z

ในสถานการณ์จริงมันจะหมายถึงx = (m - 1)ห่วงวิ่งสมบูรณ์ + ระยะห่างพิเศษZ

ดังนั้นถ้าเราวางตัวชี้หนึ่งไว้ที่จุดเริ่มต้นของรายการและปล่อยอีกจุดหนึ่งไว้ที่จุดนัดพบการเคลื่อนที่ด้วยความเร็วเดียวกันจะส่งผลให้ตัวชี้ในลูปจบการทำงานของm - 1ของการวนรอบแล้วพบอีกตัว ตัวชี้ไปทางขวาที่จุดเริ่มต้นของลูป


7
มีข้อสงสัยหนึ่งข้อ .. วิธีที่รับประกันว่าช้าและเร็วจะตอบสนองก่อนที่ช้าจะใช้เวลามากกว่าหนึ่งรอบ?
siraj

4
@siraj: ช้าจะไม่ทำงานในรอบเร็วเพราะมันจะทำงานเร็วกว่าช้าและจะเข้าสู่วงก่อน และรับประกันได้ว่าพวกเขาจะได้พบกัน หาก slow อยู่ที่ j + 1 และ fast ที่ j ตอนนี้พวกเขาจะได้พบกันที่ j + 2 และถ้า slow เป็นที่ j และ fast ที่ j + 1 ก็หมายความว่าพวกเขาพบกันที่ j - 1
displayName

4
คณิตศาสตร์ยังคงใช้งานได้หากการหมุนวนรอบช้า: x + (y + z) m + y = 2 (x + (y + z) n + y) โดยที่ n คือ # รอบของการวนรอบช้าก่อนที่จะพบกัน วิธีนี้จะแก้ (m-2n-1) (y + z) + z = x ซึ่งหมายถึงการเริ่มต้นที่จุดนัดพบ, ไปรอบ ๆ (m-2n-1), คุณกลับมาที่จุดนัดพบ, จากนั้นไปที่ z, คุณอยู่ที่จุดเริ่มต้นของลูป และเพื่อทำสิ่งนี้มันก็เหมือนกับการเริ่มต้นที่โหนดใหญ่และโหนดเอ็กซ์
mayas_mom

1
@mayas_mom: คณิตศาสตร์อาจจะทำงานได้ช้า แต่จะไม่สามารถวนไปวนมาได้ มันจะถูกจับทั้งที่เริ่มหรือกลางทาง
displayName

4
x = (m - 1) (y + z) + z สิ่งนี้สามารถสรุปได้ทั่วไปเนื่องจากความยาวของวงคือ y + z และเนื่องจากมีความเกี่ยวข้องกับตำแหน่งเท่านั้น ดังนั้น x = ((m - 1) (y + z))% (y + z)) + z ซึ่งมีประสิทธิภาพ x = z;
anshul garg

10

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

หลังจากค้นหาจุดเชื่อมต่อภายในรายการเชื่อมโยงแบบวงกลมตอนนี้ปัญหาจะลดลงเป็นการค้นหาจุดตัดของปัญหารายการที่เชื่อมโยงสองรายการ


8

รูปที่ 1

ในช่วงเวลาของการปะทะครั้งแรกเต่าขยับm + kก้าวตามที่แสดงข้างต้น กระต่ายเคลื่อนที่เร็วเป็นสองเท่าของเต่าหมายความว่ากระต่ายเคลื่อนไหว2 (m + k)ขั้นตอน จากข้อเท็จจริงง่ายๆเหล่านี้เราสามารถได้กราฟต่อไปนี้

รูปที่ 1

ณ จุดนี้เราย้ายเต่ากลับไปที่จุดเริ่มต้นและประกาศว่าทั้งกระต่ายและเต่าจะต้องเคลื่อนที่ทีละก้าว ตามคำนิยามหลังจากขั้นตอนmเต่าจะเป็นจุดเริ่มต้นของรอบ กระต่ายจะอยู่ที่ไหน

กระต่ายก็จะเป็นจุดเริ่มต้นของรอบ นี่คือที่ชัดเจนจากกราฟที่สอง: เมื่อเต่าถูกย้ายกลับไปที่จุดเริ่มต้นกระต่ายคือkก้าวเข้าสู่รอบสุดท้าย หลังจากขั้นตอนmกระต่ายจะเสร็จสิ้นรอบอื่นและชนกับเต่า


@WarrenMacEvoy ฉันไม่เคยแนะนำให้พวกเขาพบกันที่จุดเริ่มต้น พวกเขาพบกันอีกครั้งในช่วงเริ่มต้นของวงจรเมื่อตัวเลขชี้อย่างชัดเจน
skedastik

5

วิธีการ:

มีสองพอยน์เตอร์:

  • ตัวชี้แบบช้าที่เคลื่อนย้ายทีละหนึ่งโหนด
  • ตัวชี้แบบเร็วที่เคลื่อนที่สองโหนดในเวลาเดียวกัน

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

เหตุผล: เมื่อคนสองคนเดินตามทางเวียนหนึ่งในนั้นด้วยความเร็วสองเท่าของอีกคนหนึ่งพวกเขาจะพบกันที่ไหน พวกเขาเริ่มตรงไหน

ทีนี้สมมติว่านักวิ่งที่เร็วมีจุดเริ่มต้นkในnรอบตัก พวกเขาจะพบกันที่ไหน ตรงn-kตามขั้นตอน เมื่อนักวิ่งที่ช้าครอบคลุม(n-k)ขั้นตอนนักวิ่งที่เร็วจะได้ครอบคลุมk+2(n-k)ขั้นตอน ( เช่นk+2n-2kขั้นตอนคือ2n-kขั้นตอน ) เช่น(n-k)ขั้นตอน (เส้นทางเป็นแบบวงกลมและเราไม่กังวลเกี่ยวกับจำนวนรอบหลังจากที่พวกเขาพบกันเราเพียงแค่สนใจในตำแหน่งที่พวกเขาพบกัน)

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

หมายเหตุ:โหนดที่ทั้งตัวชี้พบเป็นkขั้นตอนห่างจากจุดเริ่มต้นของลูป (ภายในวง) และโหนดหัวยังเป็นkขั้นตอนห่างจากจุดเริ่มต้นของลูป ดังนั้นเมื่อเรามีพอยน์เตอร์ที่ก้าวอย่างรวดเร็วเท่ากับ 1 ก้าวจากบอทโหนดเหล่านี้พวกมันจะพบกันที่จุดเริ่มต้นของลูป

ฉันเชื่อว่ามันตรงไปตรงมา โปรดแจ้งให้เราทราบหากส่วนใดไม่ชัดเจน


4
โปรดโพสต์คำตอบแบบสมบูรณ์ที่นี่แทนที่จะเป็นเพียงลิงค์ที่อาจเกิดขึ้นในอนาคต
Leeor

4

โอเคลองสมมติว่ากระต่ายและเต่ามาพบกันที่จุดซึ่งอยู่ห่างจากจุดเริ่มต้นของ k เป็นขั้นตอนจำนวนขั้นตอนก่อนที่วงจรจะเริ่มต้นคือ mu และความยาวของวงจรคือ L

ดังนั้น ณ จุดนัดพบ ->

ระยะทางที่ครอบคลุมโดยเต่า = mu + a * L + k - สมการ 1

(ขั้นตอนที่นำไปสู่จุดเริ่มต้นของรอบ + ขั้นตอนที่ดำเนินการเพื่อครอบคลุมการทำซ้ำ 'a' ของวงจร + ขั้นตอน k จากจุดเริ่มต้นของรอบ) (โดยที่ a คือค่าคงที่ที่เป็นบวก)

ระยะทางที่ครอบคลุมโดยกระต่าย = mu + b * L + k - สมการ 2

(ขั้นตอนนำไปสู่จุดเริ่มต้นของรอบ + ขั้นตอนที่ดำเนินการเพื่อครอบคลุมการทำซ้ำ 'b' ของรอบ + k ก้าวจากจุดเริ่มต้นของรอบ) (โดยที่ b คือค่าคงที่เป็นบวกและ b> = a)

ดังนั้นระยะทางพิเศษที่ครอบคลุมโดยกระต่ายคือ = สมการ 2 - สมการ 1 = (ba) * L

โปรดทราบว่าระยะทางนี้เท่ากับระยะทางของเต่าจากจุดเริ่มต้นเนื่องจากกระต่ายเคลื่อนไหวเร็วกว่าเต่า 2 เท่า สิ่งนี้สามารถเทียบได้กับ 'mu + k' ซึ่งเป็นระยะทางของจุดนัดพบตั้งแต่ต้นถ้าเราไม่รวมการสำรวจเส้นทางหลายรอบ

ดังนั้น mu + k = (ba) * L

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

ป.ล. จริงๆแล้วฉันมีคำถามเดียวกันกับโปสเตอร์ต้นฉบับในใจของฉันและฉันอ่านคำตอบแรกพวกเขาล้างบางสิ่งออกไป แต่ฉันไม่สามารถรับผลลัพธ์สุดท้ายได้อย่างชัดเจนดังนั้นฉันจึงพยายามทำตามวิธีของตัวเองและ พบว่าง่ายต่อการเข้าใจ


พวกเขามักจะไม่พบกันที่จุดเริ่มต้นของวงจร
Warren MacEvoy

3

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

ระยะการโทรจำนวนลิงก์ที่ตัวชี้ติดตามตามมาและเวลาที่จำนวนการวนซ้ำที่อัลกอริทึมใช้ในการเลื่อนตัวชี้แบบช้าหนึ่งลิงก์และตัวชี้แบบเร็วสองลิงก์ มีโหนด N ก่อนหน้าวงจรความยาว C มีป้ายกำกับด้วยวงจรออฟเซ็ต k = 0 ถึง C-1

ในการเข้าถึงจุดเริ่มต้นของวงจรการหมุนช้าจะใช้เวลา N และระยะ ซึ่งหมายความว่าเร็วใช้ระยะทาง N ในวงจร (N เพื่อไปที่นั่นและ N เพื่อหมุน) ดังนั้นที่เวลา N, ความช้าจะอยู่ที่วัฏจักรออฟเซ็ต k = 0, และความเร็วที่รอบออฟเซ็ต k = N mod C

ถ้า N mod C เป็นศูนย์ตอนนี้ช้าและเร็วจับคู่และรอบพบในเวลา N และตำแหน่งรอบ k = 0

ถ้า N mod C ไม่เป็นศูนย์ดังนั้นตอนนี้ fast จะต้องทันกับการช้าซึ่งในเวลานั้น N คือ C- (N mod C) ระยะทางที่อยู่ด้านหลังในรอบ

เนื่องจากการเคลื่อนที่อย่างรวดเร็ว 2 สำหรับทุก ๆ 1 ของการลดระยะทางโดย 1 ในการวนซ้ำทุกครั้งนี้ใช้เวลามากขึ้นเป็นระยะห่างระหว่างเร็วและช้าในเวลาที่ N ซึ่งเป็น C- (N mod C) เนื่องจากการเคลื่อนที่ช้าจากออฟเซ็ต 0 นี่จึงเป็นออฟเซ็ตที่พบ

ดังนั้นถ้า N mod C เป็นศูนย์เฟส 1 จะหยุดหลังจากการวนซ้ำ N ที่จุดเริ่มต้นของรอบ มิฉะนั้นเฟส 1 จะหยุดหลังจากการทำซ้ำ N + C- (N mod C) ที่ offset C- (N mod C) เข้าสู่วัฏจักร

// C++ pseudocode, end() is one after last element.

int t = 0;
T *fast = begin();
T *slow = begin();
if (fast == end()) return [N=0,C=0];
for (;;) {
    t += 1;
    fast = next(fast);
    if (fast == end()) return [N=(2*t-1),C=0];
    fast = next(fast);
    if (fast == end()) return [N=(2*t),C=0];
    slow = next(slow);
    if (*fast == *slow) break;
}

ตกลงดังนั้นขั้นตอนที่ 2: ช้าใช้ N ขั้นตอนเพิ่มเติมเพื่อไปยังรอบที่จุดเร็ว (ตอนนี้ย้าย 1 ต่อขั้นตอนเวลา) อยู่ที่ (C- (N mod C) + N) mod C = 0 พวกเขาพบ ที่จุดเริ่มต้นของวงจรหลังเฟส 2

int N = 0;
slow = begin();
for (;;) {
    if (*fast == *slow) break;
    fast = next(fast);
    slow = next(slow);
    N += 1;
}

เพื่อความสมบูรณ์เฟส 3 คำนวณความยาวของวงจรโดยเลื่อนอีกครั้งผ่านวงจร:

int C = 0;
for (;;) {
    fast = next(fast);
    C += 1;
    if (fast == slow) break;
}

เชื่อมโยงไปยัง google doc เพื่อจำลองอัลกอริทึม: docs.google.com/spreadsheets/d/…
Warren MacEvoy

1
โปรดทราบว่าถ้า N <= C การทำซ้ำจะหยุดหลังจากการทำซ้ำ C ไม่ว่าในกรณีใดจะต้องหยุดในเวลาน้อยกว่า N + C และไม่น่าจะหยุดที่จุดเริ่มต้นของรอบ
Warren MacEvoy

2

ลดปัญหาให้เป็นปัญหาลูปจากนั้นกลับไปที่ปัญหาเริ่มต้น

ฉันพบว่าคำอธิบายต่อไปนี้ใช้งานง่ายขึ้น

  1. ใช้เวลาสองชี้ ( 1 = เต่าและ2 = กระต่าย) ที่เริ่มต้นจากหัว ( O ) 1มีความยาวขั้นตอนของ1 , 2มีความยาวขั้นตอนของ2 ลองนึกถึงช่วงเวลาที่1ถึงโหนดเริ่มต้นของรอบนั้น ( A )

    เราต้องการที่จะตอบคำถามต่อไปนี้"อยู่ที่ไหน 2 เมื่อ 1 อยู่ใน A".

    ดังนั้นOA = aเป็นจำนวนธรรมชาติ ( a >= 0) แต่สามารถเขียนได้ด้วยวิธีต่อไปนี้: a = k*n + b, ที่ไหนa, k, n, b are natural numbers:

    • n = ความยาวรอบ
    • k >= 0 = ค่าคงที่
    • 0 <= b <= n-1

    มันหมายความว่า b = a % nก็หมายความว่า

    เช่น: ถ้าa = 20และn = 8=> k = 2และb = 4เพราะ20 = 2*8 + 4เพราะ

    ระยะทางที่ครอบคลุมโดย1d = OA = a = k*n + bคือ แต่ในเวลาเดียวกัน2D = 2*d = d + d = OA + d = OA + k*n + bครอบคลุม ซึ่งหมายความว่าเมื่อ2k*n + bอยู่ในมันจะต้องมีฝาครอบ ในขณะที่คุณสามารถดูkเป็นจำนวนรอบ แต่หลังจากรอบนั้น2จะไกลจาก A. ดังนั้นเราพบที่2คือเมื่อ1อยู่ในโทร A. Let 's ที่จุดที่BAB = b

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

  2. ตอนนี้เราลดปัญหาเป็นวงกลม คำถามคือ"จุดนัดพบอยู่ที่ไหน" . คือว่าอยู่ที่ไหนC ?

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

    ในทุกขั้นตอน2ลดระยะทางจาก1ด้วย1(สมมติว่ามิเตอร์) เพราะ1เพิ่มขึ้นจาก2ด้วย1แต่ในเวลาเดียวกัน2เข้าใกล้1โดย2โดย

    ดังนั้นทางแยกจะเป็นเมื่อระยะทางระหว่าง1ถึง2จะเป็นศูนย์ ซึ่งหมายความว่า2ช่วยลดn - bระยะทาง เพื่อให้บรรลุนี้1จะทำn - bตามขั้นตอนในขณะที่2จะทำ2*(n - b)ตามขั้นตอน

    ดังนั้นจุดตัดจะn - bห่างไกลจาก(ตามเข็มนาฬิกา) เพราะนี้คือระยะทางที่ครอบคลุมโดย1จนกว่าจะได้พบกับ2 => ระยะห่างระหว่างCและเป็นเพราะและ อย่าคิดว่าเพราะระยะทางไม่ใช่ระยะทางคณิตศาสตร์ที่น่าสนใจมันเป็นจำนวนขั้นตอนระหว่างAและC (โดยที่Aคือจุดเริ่มต้นและCคือจุดสิ้นสุด)CA = bAC = AB + BC = n - bCA = n - ACAC = CAAC

  3. ทีนี้กลับไปที่สคีมาเริ่มต้นกัน

    เรารู้ว่าa = k*n + bและCA = bและ

    เราสามารถใช้ตัวชี้ 2 ใหม่1 'และ1' 'โดยที่1'เริ่มจากหัว ( O ) และ1 ''เริ่มจากจุดตัด ( C) )

    ในขณะที่1 'ไปจากOถึงA , 1' 'ไปจากCถึงAและสิ้นสุดkรอบต่อไป ดังนั้นจุดตัดคือ

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

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


2

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

หากตัวชี้พบที่จุด P ดังแสดงในรูประยะทาง Z + Y คือจุด P และ X + Y เป็นจุด P ซึ่งหมายถึง Z = X ซึ่งเป็นสาเหตุที่ทำให้การย้ายตัวชี้หนึ่งจาก P และการย้ายอีกครั้งจากจุดเริ่มต้น (S) จนกระทั่งพวกเขาพบซึ่งหมายความว่าการย้ายระยะทางเท่ากับ (Z หรือ X) ไปยังจุดเดียวกัน M (ระยะทาง Z จาก P และ X จาก S) จะ เริ่มจากวนรอบ ! ง่าย


1

จากการวิเคราะห์ทั้งหมดข้างต้นหากคุณเป็นบุคคลที่เรียนรู้โดยตัวอย่างฉันพยายามเขียนการวิเคราะห์สั้น ๆ และตัวอย่างที่ช่วยอธิบายคณิตศาสตร์ที่ทุกคนพยายามอธิบาย ไปเลย!

วิเคราะห์:

หากเรามีพอยน์เตอร์สองตัวตัวใดตัวหนึ่งเร็วกว่าตัวอื่นและย้ายพวกมันไปด้วยกันพวกมันจะพบกันอีกครั้งเพื่อระบุวัฏจักรหรือโมฆะเพื่อระบุว่าไม่มีวัฏจักรใด

เพื่อหาจุดเริ่มต้นของวัฏจักรปล่อยให้ ...

  1. m เป็นระยะทางจากหัวถึงจุดเริ่มต้นของวงจร

  2. d เป็นจำนวนโหนดในวงจร

  3. p1 เป็นความเร็วของตัวชี้ช้า;

  4. p2เป็นความเร็วของตัวชี้ที่เร็วขึ้นเช่น 2 หมายถึงขั้นตอนผ่านสองโหนดต่อครั้ง

    สังเกตการทำซ้ำต่อไปนี้:

 m = 0, d = 10:
 p1 = 1:  0  1  2  3  4  5  6  7  8  9 10 // 0 would the start of the cycle
 p2 = 2:  0  2  4  6  8 10 12 14 16 18 20

 m = 1, d = 10:
 p1 = 1: -1  0  1  2  3  4  5  6  7  8  9
 p2 = 2: -1  1  3  5  7  9 11 13 15 17 19

 m = 2, d = 10:
 p1 = 1: -2 -1  0  1  2  3  4  5  6  7  8
 p2 = 2: -2  0  2  4  6  8 10 12 14 16 18

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


1

สมมติว่า

N[0] is the node of start of the loop, 
m is the number of steps from beginning to N[0].

เรามี 2 พอยน์เตอร์ A และ B, A วิ่งที่ 1x speed, B ที่ 2x speed, ทั้งสองเริ่มต้นที่จุดเริ่มต้น

เมื่อ A ถึง N [0], B ควรอยู่ใน N [m] (หมายเหตุ: A ใช้ขั้นตอน m ในการเข้าถึง N [0] และ B ควรเป็นขั้นตอน m เพิ่มเติม)

จากนั้น A จะวิ่งไปอีกก้าวหนึ่งเพื่อชนกับ B นั่นคือ A อยู่ที่ N [k], B อยู่ที่ N [m + 2k] (หมายเหตุ: B ควรวิ่งเป็นระยะ 2k เริ่มต้นจาก N [m])

การชน B ที่ N [k] และ N [m + 2k] ตามลำดับมันหมายถึง k = m + 2k ดังนั้น k = -m

ดังนั้นในการวนกลับไปที่ N [0] จาก N [k] เราต้องมีขั้นตอนมากขึ้น

เพียงแค่บอกว่าเราเพียงแค่เรียกใช้ขั้นตอนเพิ่มเติมหลังจากที่เราพบโหนดการชน เราสามารถมีตัวชี้ให้เรียกใช้จากจุดเริ่มต้นและตัวชี้ที่เรียกใช้จากโหนดการชนกันพวกเขาจะพบกันที่ N [0] หลังจากขั้นตอน m

ดังนั้นรหัสหลอกมีดังนี้:

1) A increase 1 step per loop
2) B increase 2 steps per loop
3) if A & B are the same node, cycle found, then go to 5
4) repeat from 1
5) A reset to head
6) A increase 1 step per loop
7) B increase 1 step per loop
8) if A & B are the same node, start of the cycle found
9) repeat from 6

1

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

1->2->3->4->5->6->7->8->9->10->11->12->13->14->15->16->17->18->19->20->21->22->23->24->8

Meet at :16

Start at :8

public Node meetNodeInLoop(){

    Node fast=head;
    Node slow=head;

    fast=fast.next.next;
    slow=slow.next;

    while(fast!=slow){

        fast=fast.next;
        fast=fast.next;

        if(fast==slow) break; 

        slow=slow.next;
    }

    return fast;

}

public Node startOfLoop(Node meet){

    Node slow=head;
    Node fast=meet;

    while(slow!=fast){
        fast=fast.next;
        if(slow==fast.next) break;
        slow=slow.next;
    }

    return slow;
}

1

คำอธิบายง่ายๆโดยใช้แนวคิดเรื่องความเร็วสัมพัทธ์ที่สอนในโรงเรียนมัธยม - วิชาฟิสิกส์ 101 / Kinematics

วงกลมใน LinkedList

  1. สมมติว่าระยะทางจากจุดเริ่มต้นของรายการที่เชื่อมโยงไปยังจุดเริ่มต้นของวงกลมคือxฮ็อพ มาเรียกจุดเริ่มต้นของวงกลมว่าเป็นจุดX(เป็นตัวพิมพ์ใหญ่ - ดูรูปด้านบน) สมมุติว่าขนาดทั้งหมดของวงกลมคือ N hops

  2. ความเร็วของกระต่าย = 2 * ความเร็วของเต่า นั่นคือ1 hops/secและ2 hops/secตามลำดับ

  3. เมื่อเต่ามาถึงจุดเริ่มต้นของวงกลมXกระต่ายจะต้องxกระโดดต่อไปที่จุดYในรูป (เพราะกระต่ายได้เดินทางไกลเป็นสองเท่าของเต่า)

  4. ดังนั้นระยะเวลาที่เหลือโค้งตามเข็มนาฬิกาจาก X เป็น Y N-xจะเป็น T ของเขายังเกิดขึ้นเป็นระยะทางญาติได้รับการคุ้มครองระหว่างกระต่ายกับเต่าสำหรับพวกเขาที่จะสามารถตอบสนองความต้องการ สมมติว่าระยะทางสัมพัทธ์นี้จะครอบคลุมในเวลาt_mเช่นเวลาที่จะตอบสนอง ความเร็วสัมพัทธ์คือคือ(2 hops/sec - 1 hops/sec) 1 hops/secดังนั้นการใช้, ระยะทางสัมพัทธ์ = เวลาสัมพัทธ์ X เราจะได้, t= N-xวินาที ดังนั้นมันจะN-xไปถึงจุดนัดพบสำหรับทั้งเต่าและกระต่าย

  5. ตอนนี้ในN-xเวลาวินาทีและ1 hops/secความเร็วเต่าที่ก่อนหน้านี้ที่จุดXจะครอบคลุม Nx Mกระโดดไปถึงจุดนัดพบ ดังนั้นนั่นหมายความว่าจุดนัดพบMอยู่ที่N-xhops ทวนเข็มนาฬิกาจากX= (ซึ่งหมายถึงเพิ่มเติม) => ว่ามีxระยะทางที่เหลือจากจุดหนึ่งMไปยังอีกมุมหนึ่งXตามเข็มนาฬิกา

  6. แต่xยังเป็นระยะทางถึงจุดXเริ่มต้นของรายการที่ลิงก์

  7. ตอนนี้เราไม่สนใจว่าจำนวนฮ็อพxตรงกับอะไร หากเราใส่เต่าหนึ่งตัวที่จุดเริ่มต้นของ LinkedList และเต่าหนึ่งตัวที่จุดนัดพบMและปล่อยให้พวกเขากระโดด / เดินพวกเขาจะพบกันที่จุดXซึ่งเป็นจุด (หรือโหนด) ที่เราต้องการ


1

การทำงานกับไดอะแกรมจะช่วยได้ ฉันพยายามอธิบายปัญหาโดยปราศจากสมการ

  1. ถ้าเราปล่อยให้กระต่ายและเต่าวิ่งวนเป็นวงกลมและกระต่ายวิ่งสองครั้งแล้วเมื่อสิ้นสุดรอบหนึ่งสำหรับกระต่ายป่าก็จะครึ่ง ในตอนท้ายของสองรอบจากเต่ากระต่ายจะทำ 1 รอบและพวกเขาทั้งสองพบกัน สิ่งนี้ใช้กับทุกความเร็วเช่นถ้ากระต่ายวิ่งสามครั้งกระต่าย 1 รอบมีค่าเท่ากับ 1/3 ของเต่าดังนั้นเมื่อสิ้นสุดรอบ 3 รอบสำหรับเต่ากระต่ายจะครอบคลุม 1 รอบและพวกเขาพบกัน
  2. ตอนนี้ถ้าเราเริ่มต้นพวกมัน m ก่อนที่จะวนรอบมันก็หมายความว่ากระต่ายที่เร็วขึ้นกำลังเริ่มไปข้างหน้าเป็นวง ดังนั้นหากเต่ามาถึงจุดเริ่มต้นของลูปกระต่ายคือ m ก้าวไปข้างหน้าลูปและเมื่อพวกเขาพบกันมันจะเป็นขั้นตอน m ก่อนที่ลูปจะเริ่ม

1

- มี k ก้าวก่อนลูป เราไม่รู้ว่า k คืออะไรและไม่จำเป็นต้องค้นหา เราสามารถทำงานอย่างเป็นนามธรรมด้วยเพียง k

- หลังจากขั้นตอน k

----- T อยู่ที่จุดเริ่มต้นของรอบ

----- H คือ k ก้าวเข้าสู่วงจร (เขารวม 2k และทำให้ k เข้าสู่วง)

** พวกมันแยกออกจากกันแล้ว - แยก

(โปรดทราบว่า k == K == mod (loopsize, k) - หากว่าโหนดเป็น 2 ขั้นตอนในวัฏจักร 5 โหนดมันก็เป็นขั้นตอน 7, 12 หรือ 392 ดังนั้น wrt k จึงไม่ใหญ่ ปัจจัยใน

เนื่องจากพวกเขาติดต่อกันด้วยอัตรา 1 ขั้นต่อหน่วยของเวลาเนื่องจากมีการเคลื่อนที่เร็วเป็นสองเท่าเมื่อเปรียบเทียบกันพวกเขาจะพบกันที่ลูป - k

ซึ่งหมายความว่าจะต้องใช้โหนด k เพื่อไปยังจุดเริ่มต้นของวัฏจักรและทำให้ระยะห่างจากหัวถึง cyclestart และการชนกับ cyclestart เหมือนกัน

ดังนั้นตอนนี้หลังจากการชนครั้งแรกย้าย T กลับไปที่หัว T และ H จะพบกันที่ cyclestart ถ้าคุณเคลื่อนที่ด้วยอัตรา 1 ต่อ (ในขั้นตอน k สำหรับทั้งสอง)

ซึ่งหมายความว่าอัลกอริทึมคือ:

  • จากการย้ายส่วนหัว T = t.next และ H.next.next จนกระทั่งชนกัน (T == H) (มีรอบ)

// ดูแลเคสเมื่อ k = 0 หรือ T และ H พบกันที่หัวของลูปโดยการคำนวณความยาวของลูป

- นับความยาวของวงจรโดยการย้าย T หรือ H รอบมันด้วยเคาน์เตอร์

- ย้ายตัวชี้ T2 ไปยังส่วนหัวของรายการ

- ย้ายตัวชี้ความยาวของขั้นตอนรอบ

- ย้ายตัวชี้ H2 อื่นไปที่หัว

- เคลื่อนย้าย T2 และ H2 ไปพร้อมกันจนกว่าจะถึงจุดเริ่มต้นของรอบ

แค่นั้นแหละ!


1

มีคำตอบมากมายเกี่ยวกับสิ่งนี้ แต่ฉันเคยมีไดอะแกรมสำหรับสิ่งนี้ซึ่งทำให้ฉันเห็นได้ง่ายกว่า อาจช่วยคนอื่นได้

ช่วงเวลา aha หลักสำหรับฉันคือ:

  • แยกT (เต่า) เป็นT1 (pre-loop) และT2 (in-loop) T = เต่า, H = กระต่าย

  • ลบTจากHซึ่งพวกมันซ้อนทับภาพ สิ่งที่เหลืออยู่ ( H - T = H' ) เท่ากับT

  • คณิตศาสตร์ที่เหลืออยู่นั้นค่อนข้างง่าย จาก H ให้ลบที่ T ทับด้วยสายตา

-1

ฉันรู้ว่ามีคำตอบที่ยอมรับแล้วสำหรับปัญหานี้ แต่ฉันยังคงพยายามตอบอย่างคล่องแคล่ว สมมติ :

The length of the Path is 'X+B' where 'B' is the length of the looped path and X of the non looped path. 
    Speed of tortoise : v
    Speed of hare     : 2*v 
    Point where both meet is at a distance 'x + b - k' from the starting point.

ตอนนี้ให้กระต่ายและเต่าพบกันหลังจากเวลา 't' ตั้งแต่ต้น

ข้อสังเกต:

ถ้าระยะทางเดินทางโดยเต่า = v * t = x + (bk) (พูด)

จากนั้นระยะทางที่เดินทางโดยกระต่าย = 2 * v * t = x + (b - k) + b (เนื่องจากกระต่ายได้สำรวจส่วนที่วนลูปไว้แล้ว)

ขณะนี้มีเวลาการประชุมเหมือนกัน

=> x + 2 * b - k = 2 * (x + b - k)

=> x = k

หลักสูตรนี้หมายความว่าความยาวของเส้นทางที่ไม่ได้วนซ้ำนั้นเท่ากับระยะทางของจุดเริ่มต้นของลูปจากจุดที่ทั้งคู่พบกัน


คุณไม่สามารถสรุปได้ว่าเต่านั้นเดินทาง x + bk ทุกครั้งที่พบกัน นอกจากนี้ฉันไม่เข้าใจว่าคุณได้ x + 2 * bk สำหรับระยะทางของกระต่ายได้อย่างไร
Plumenator

เพราะกระต่ายจะผ่านส่วนที่วนไปวนมาแล้วต้องไปพบกับเต่า .. ฉันไม่ได้อธิบายที่นั่น: /
n0nChun

-1

เป็นเรื่องง่ายที่จะพิสูจน์ว่าพวกเขาทั้งคู่จะพบกันที่จุดเริ่มต้นหากคุณพิจารณาคณิตศาสตร์หลังจุดนัดพบ
ก่อนอื่นให้mแทนจุดเริ่มต้นของวงจรในรายการที่เชื่อมโยงและnแทนความยาวของรอบ จากนั้นสำหรับกระต่ายและเต่าที่จะพบกันเรามี:

( 2*t - m )%n = (t - m) %n, where t = time (at t = 0 , both are at the start)

ระบุเพิ่มเติมในเชิงคณิตศาสตร์:

(2*t - m - (t - m) ) = 0 modulo n , which implies , t = 0 modulo n 

ดังนั้นพวกเขาจะได้พบกันในเวลาtซึ่งควรจะมีความยาวหลายรอบ ซึ่งหมายความว่าพวกเขาพบกันในสถานที่ซึ่งเป็น (t-m) modulo n = (0-m) modulo n = (-m) modulo nซึ่งหมายความว่าพวกเขาพบกันที่สถานที่ซึ่งเป็น

ตอนนี้กลับมาที่คำถามถ้าคุณย้ายตัวชี้หนึ่งจากจุดเริ่มต้นของรายการที่เชื่อมโยงและอีกจุดจากจุดตัดหลังจากขั้นตอน m เราจะมีกระต่าย (ซึ่งเคลื่อนที่ภายในวงรอบ) มาถึงจุดที่เป็น((-m) + m) modulo n = 0 modulo nซึ่งไม่มีอะไรนอกจากเป็นจุดเริ่มต้นของวัฏจักรดังนั้นเราจะเห็นว่าหลังจากขั้นตอนม. มันมาถึงจุดเริ่มต้นของวงจรและเต่าจะพบมันที่นั่นตามที่จะสำรวจม. ขั้นตอนจากจุดเริ่มต้นของรายการที่เชื่อมโยง

ตามบันทึกข้างเรายังสามารถคำนวณเวลาของสี่แยกของพวกเขาในลักษณะนี้: สภาพt = 0 modulo nบอกเราว่าพวกเขาจะได้พบกับช่วงเวลาที่มีหลายความยาวรอบและยังเสื้อควรมากกว่าเมตรที่พวกเขาจะได้พบใน วงจร ดังนั้นเวลาที่ถ่ายจะเท่ากับหลายแรกของnซึ่งมากกว่าเมตร


พวกเขาไม่จำเป็นต้องพบกันเมื่อเริ่มต้นรอบ
Warren MacEvoy

-1

สมมติว่าพอยน์เตอร์ของคุณพบกันที่จุดตัดของ y และ z

n และ m คือจำนวนของลูปที่เร็วขึ้นและตัวชี้ที่ช้าจะใช้เวลาตามลำดับก่อนการประชุม

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

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