मैं समझता हूं कि कछुआ और हरे की बैठक लूप के अस्तित्व को समाप्त करती है, लेकिन बैठक की जगह पर हरेक को रखते हुए कछुआ को चलती सूची में कैसे ले जाया जाता है, एक समय में दोनों एक कदम को आगे बढ़ाते हुए उन्हें चक्र के प्रारंभिक बिंदु पर मिलते हैं?
मैं समझता हूं कि कछुआ और हरे की बैठक लूप के अस्तित्व को समाप्त करती है, लेकिन बैठक की जगह पर हरेक को रखते हुए कछुआ को चलती सूची में कैसे ले जाया जाता है, एक समय में दोनों एक कदम को आगे बढ़ाते हुए उन्हें चक्र के प्रारंभिक बिंदु पर मिलते हैं?
जवाबों:
यह साइकल डिटेक्शन के लिए फ्लोयड का एल्गोरिदम है । आप एल्गोरिथ्म के दूसरे चरण के बारे में पूछ रहे हैं - एक बार जब आपको एक नोड मिल जाता है जो एक चक्र का हिस्सा होता है, तो चक्र की शुरुआत कैसे होती है?
फ़्लॉइड के एल्गोरिथ्म के पहले भाग में, हर कछुआ के हर कदम के लिए दो कदम चलते हैं। यदि कछुआ और खरगोश कभी मिलते हैं, तो एक चक्र होता है, और बैठक बिंदु चक्र का हिस्सा होता है, लेकिन जरूरी नहीं कि चक्र में पहला नोड हो।
जब कछुआ और खरगोश मिलते हैं, तो हमने सबसे छोटा i (कछुए द्वारा उठाए गए कदमों की संख्या) पाया है जैसे कि X i = X 2i । मान लें कि एक्स 0 से चक्र की शुरुआत के लिए चरणों की संख्या का प्रतिनिधित्व करें , और लैम्ब्डा को चक्र की लंबाई का प्रतिनिधित्व करने दें। तब i = mu + a lambda, और 2i = mu + b lambda, जहां a और b पूर्णांक हैं, जो यह दर्शाता है कि चक्र के चारों ओर कछुआ और खरगोश कितनी बार गए हैं। दूसरे से पहले समीकरण को घटाना i = (ba) * लैम्ब्डा देता है, इसलिए मैं लैम्ब्डा का एक पूर्णांक एकाधिक हूं। इसलिए, एक्स i + म्यू = एक्स म्यू । X i कछुआ और हरे के मिलन बिंदु का प्रतिनिधित्व करता है। यदि आप कछुआ वापस प्रारंभिक नोड X में ले जाते हैं0 , और कछुए और खरगोश को एक ही गति से जारी रखने दें, म्यू अतिरिक्त चरणों के बाद कछुआ एक्स म्यू तक पहुंच गया होगा , और हर एक्स एक्स + म्यू = एक्स म्यू तक पहुंच गया होगा , इसलिए दूसरी बैठक बिंदु की शुरुआत को दर्शाता है चक्र।
X_mu
, (म्यू की परिभाषा द्वारा) करने के लिए प्रारंभ बिंदु से म्यू चरण लें । फिर यदि आप अधिक कदम उठाते हैं, जहां मैं चक्र की लंबाई से कई गुना अधिक है, तो आप चक्र शुरू होने पर वापस समाप्त होते हैं: X_mu + i
= X_mu
। लेकिन इसके अलावा सराहनीय है, इसलिए यह पहली बैठक बिंदु से शुरू करने के लिए i कदम उठाने के बराबर है X_i
, फिर X_mu
चक्र को शुरू करने के लिए अतिरिक्त चरणों को वापस लेने के लिए एमयू अतिरिक्त कदम उठाएं ।
i
चक्र के कुछ बिंदु पर है, मुझे लगता है कि समीकरण होना चाहिए i = mu + k + a*lambda
और 2i = mu + k + b*lambda
, जहां k
चक्र से कदम की संख्या बैठक बिंदु तक है। हालांकि दोनों समीकरणों को घटाना एक ही परिणाम देता है।
मुझे अपने स्वयं के शब्दों में http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare पर प्रदान की गई साइकिल डिटेक्शन एल्गोरिदम को स्पष्ट करने का प्रयास करने दें ।
यह काम किस प्रकार करता है
चलो एक चक्र के साथ सूची की शुरुआत की ओर इशारा करते हुए एक कछुआ और एक खरगोश (बिंदुओं का नाम) है, जैसा कि ऊपर चित्र में है।
चलो परिकल्पना करते हैं कि अगर हम एक समय में 1 कदम कछुआ और एक बार में 2 कदम आगे बढ़ते हैं, तो वे अंततः एक बिंदु पर मिलेंगे। आइए दिखाते हैं कि सबसे पहले यह परिकल्पना सच है।
आंकड़ा एक सूची को एक चक्र के साथ दिखाता है। चक्र की लंबाई है 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
मी, एन, के, पी, क्यू, पहले दो दिए गए सूची के गुण हैं। यदि हम दिखा सकते हैं कि 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.
बेशक, आपको यह देखना चाहिए कि यह सबसे छोटा संभव नहीं है। दूसरे शब्दों में, कछुआ और खरगोश कई बार पहले ही मिल चुके होंगे। हालाँकि, जब से हम दिखाते हैं कि वे कम से कम एक बार मिलते हैं तो हम कह सकते हैं कि यह परिकल्पना सही है। इसलिए उन्हें मिलना होगा अगर हम उनमें से एक को 1 कदम और एक समय में अन्य 2 चरणों को पूरा करते हैं।
अब हम एल्गोरिथ्म के दूसरे भाग पर जा सकते हैं जो चक्र की शुरुआत का पता लगाने का तरीका है।
साइकिल की शुरुआत
एक बार कछुआ और हरे मिलने के बाद, चलो कछुए को सूची की शुरुआत में वापस रख दें और जहां वे मिले (जो कि चक्र की शुरुआत से k कदम दूर है) में खरगोश रखें।
परिकल्पना यह है कि अगर हम उन्हें एक ही गति (दोनों के लिए 1 कदम) पर जाने देते हैं, तो पहली बार जब वे फिर से मिलेंगे तो चक्र की शुरुआत होगी।
आइये इस परिकल्पना को सिद्ध करते हैं।
आइए पहले मान लें कि कुछ ओरेकल हमें बताता है कि एम क्या है।
फिर, अगर हम उन्हें m + k कदम उठाने देते हैं, तो कछुआ को उस बिंदु पर पहुंचना होगा जो वे मूल रूप से मिले थे (चक्र की शुरुआत से कदम दूर - चित्र में देखें)।
पहले हमने दिखाया था m + k = (q - 2p) n
।
चूँकि m + k चरण चक्र की लंबाई n, hare का एक गुणक है, इस दौरान, चक्र (q-2p) बार के माध्यम से जाएगा और उसी बिंदु पर वापस आएगा (चक्र की शुरुआत से कदम दूर)।
अब, उन्हें m + k चरणों को स्थानांतरित करने देने के बजाय, यदि हम उन्हें केवल m कदम आगे बढ़ने देते हैं, तो कछुआ चक्र की शुरुआत में आ जाएगा। हरे (k-2p) घुमावों को पूरा करने के लिए k कदम कम होगा। चूँकि यह चक्र की शुरुआत के सामने k कदम उठाता है, इसलिए हरेक को चक्र की शुरुआत में पहुंचना होगा।
परिणामस्वरूप, यह बताता है कि उन्हें पहली बार कुछ कदमों के बाद चक्र पर मिलना होगा (बहुत पहली बार क्योंकि कछुआ सिर्फ m चरणों के बाद चक्र पर आया था और यह कभी नहीं देख सकता था जो पहले से ही था साईकिल)।
अब हम जानते हैं कि हमें मिलने तक जितने चरणों की आवश्यकता होती है, वे सूची की शुरुआत से लेकर चक्र की शुरुआत, मी तक की दूरी तय करते हैं। बेशक, एल्गोरिथ्म को यह जानने की आवश्यकता नहीं है कि एम क्या है। यह बस कछुआ और खरगोश दोनों को एक समय में एक कदम आगे बढ़ाएगा, जब तक वे मिलते नहीं हैं। बैठक बिंदु को चक्र शुरू होना चाहिए और चरणों की संख्या चक्र की शुरुआत के लिए दूरी (एम) होनी चाहिए। यह मानते हुए कि हम सूची की लंबाई जानते हैं, हम भी सूची लंबाई से मीटर घटा के चक्र की लंबाई की गणना कर सकते हैं।
m + k = (q - 2p) n
को और सरल बनाया जा सकता है m + k = q*n
। ऐसा इसलिए है क्योंकि लूप कछुआ की संख्या हमेशा शून्य होगी क्योंकि खरगोश कभी भी कछुए को बिना मिले उससे आगे नहीं निकल सकता है। इसके बारे में सोचो।
इस छवि को देखें:
बैठक से पहले धीमी गति से यात्रा की दूरी = x + y
मिलने से पहले फास्टपाइंटर से यात्रा की गई दूरी = (x + y + z) + y = x + 2y + z
चूंकि फास्टपॉइंट धीमी गति से दोगुनी गति से यात्रा करता है, और बैठक बिंदु तक पहुंचने पर समय दोनों के लिए स्थिर होता है।
तो सरल गति, समय और दूरी संबंध 2 (x + y) = x + 2y + z => x + 2y + z = 2x + 2y => x = z का उपयोग करके
इसलिए लिंक्ड लिस्ट की शुरुआत करने के लिए स्लोपॉइंट को मूव करके , और एक बार में एक नोड को स्थानांतरित करने के लिए स्लोपॉइंट और फास्टपॉइंट दोनों को बनाकर, वे दोनों को कवर करने के लिए समान दूरी रखते हैं ।
वे उस बिंदु पर पहुंच जाएंगे जहां लिंक की गई सूची में लूप शुरू होता है।
ओल्ड मॉन्क का सरल और कमज़ोर उत्तर , चक्र को खोजने के बारे में बताता है जब तेज़ धावक केवल एकल पूर्ण चक्र पूरा करता है। इस उत्तर में मैं उस मामले की व्याख्या करता हूं जब धीमी गति से चलने वाले लूप में प्रवेश करने से पहले तेज धावक ने कई बार लूप चलाया है।
बता दें कि फास्ट रनर धीमी और तेज मुलाकात से पहले लूप m को चला चुके हैं । इस का मतलब है कि:
चूंकि तेजी धीमी गति से दोगुनी गति से चलती है, और यह कि वे एक ही समय के लिए चल रहे हैं, इसका अर्थ है कि यदि हम दूरी को धीमी गति से दौड़ाते हैं, तो हम दूरी को तेजी से दौड़ाते हैं। इस प्रकार,
एक्स के लिए हल देता है,
x = (m - 1) (y + z) + z
वास्तविक परिदृश्य में इसका मतलब होगा, x = (m - 1) पूर्ण लूप रन + एक अतिरिक्त दूरी z ।
इसलिए, यदि हम सूची के शुरू में एक पॉइंटर डालते हैं और दूसरे को मीटिंग पॉइंट पर छोड़ते हैं, तो उन्हें उसी गति से आगे बढ़ाने से लूप पॉइंटर पूरा हो जाएगा - लूप के 1 रन और फिर दूसरे से मिलना लूप शुरुआत में सूचक सही।
यह बहुत सरल है। आप सापेक्ष गति के संदर्भ में सोच सकते हैं। यदि खरगोश दो नोड चलता है और कछुआ एक नोड चलता है, तो कछुआ खरगोश के सापेक्ष एक नोड बढ़ रहा है (बाकी पर कछुआ मान लीजिए)। इसलिए, यदि हम एक नोड को सर्कुलर लिंक्ड सूची में ले जाते हैं, तो हम निश्चित रूप से उस बिंदु पर फिर से मिलने वाले हैं।
सर्कुलर लिंक्ड लिस्ट के अंदर जुड़े बिंदु को खोजने के बाद, अब दो लिंक्ड लिस्ट की समस्या के प्रतिच्छेदन बिंदु को खोजने के लिए समस्या कम हो गई है।
पहली टक्कर के समय, कछुआ m + k चरणों को ऊपर दिखाए गए अनुसार दिखाता है। हरे कछुए के रूप में दो बार तेज चलता है, जिसका अर्थ है हरे 2 (एम + के) कदम। इन सरल तथ्यों से हम निम्नलिखित ग्राफ को प्राप्त कर सकते हैं।
इस बिंदु पर, हम कछुआ को फिर से शुरू करते हैं और घोषणा करते हैं कि हरे और कछुआ दोनों को एक बार में एक कदम आगे बढ़ना चाहिए। परिभाषा के अनुसार, एम चरणों के बाद , चक्र की शुरुआत में कछुआ होगा। हारे कहां होंगे?
चक्र की शुरुआत में हरेला भी होगा। यह दूसरे ग्राफ से स्पष्ट है: जब कछुआ को वापस शुरू किया गया था, तो हरे अपने आखिरी चक्र में k कदम था । एम स्टेप्स के बाद , हरे ने एक और चक्र पूरा किया और कछुए से टकरा गया।
दृष्टिकोण:
दो बिंदु हैं:
यदि दो पॉइंटर मिलते हैं, तो यह साबित होता है कि लूप है। एक बार मिलने के बाद, नोड्स में से एक सिर को इंगित करेगा और फिर एक समय में दोनों एक नोड को आगे बढ़ाएगा। वे लूप की शुरुआत में मिलेंगे।
Rationale: जब दो लोग एक वृत्ताकार ट्रैक से नीचे जाते हैं, तो उनमें से एक दूसरे की गति से दोगुना होता है, वे कहाँ मिलते हैं? बिल्कुल वही जहां उन्होंने शुरू किया था।
अब, मान लीजिए कि तेज धावक के पास एक कदम गोद k
में कदम रखने की शुरुआत है n
। वे कहाँ मिलेंगे बिल्कुल n-k
कदमों पर। जब धीमे धावक ने (n-k)
कदमों को ढक दिया होता है, तो तेज धावक k+2(n-k)
कदमों को ढंक लेता है। ( अर्थात, k+2n-2k
चरण अर्थात 2n-k
चरण )। अर्थात (n-k)
चरण (पथ वृत्ताकार है और हम गोल होने की संख्या के बारे में चिंतित नहीं हैं, जिसके बाद वे मिलते हैं; हम सिर्फ उस स्थिति में रुचि रखते हैं, जहाँ वे मिलते हैं)।
अब तेज धावक k
को पहले स्थान पर कदमों की शुरुआत कैसे मिली ? क्योंकि इसने धीमे धावक को लिया कि लूप की शुरुआत तक पहुंचने के लिए कई कदम उठाए। तो लूप की शुरुआत सिर के नोड से कदम है।
नोट: वह नोड जहां दोनों पॉइंटर मिले थे k
, लूप की शुरुआत (लूप के अंदर) k
से दूर है और हेड नोड भी लूप के शुरू होने से दूर है। इसलिए जब हमारे पास इन नोड्स से बॉट से 1 कदम की समान गति पर सूचक है, तो वे लूप की शुरुआत में मिलेंगे।
मेरा मानना है कि यह सीधा है। कृपया मुझे बताएं कि क्या कोई हिस्सा अस्पष्ट है।
ठीक है इसलिए मान लेते हैं कि खरगोश और कछुआ एक बिंदु पर मिलते हैं जो चक्र के शुरू होने से कदम दूर है, चक्र शुरू होने से पहले चरणों की संख्या म्यू है और चक्र की लंबाई एल है।
तो अब बैठक बिंदु पर ->
कछुआ = mu + a * L + k - समीकरण 1 द्वारा तय की गई दूरी
(चक्र की शुरुआत तक पहुंचने के लिए उठाए गए कदम + चक्र की शुरुआत से 'पुनरावृत्तियों को कवर करने के लिए उठाए गए कदम + चक्र की शुरुआत से कदम) (जहां एक सकारात्मक कुछ है)
हरे द्वारा तय की गई दूरी = म्यू + बी * एल + के - समीकरण 2
(चक्र की शुरुआत तक पहुंचने के लिए उठाए गए कदम + चक्र की शुरुआत से 'बी' पुनरावृत्तियों को कवर करने के लिए उठाए गए कदम) (जहां b कुछ सकारात्मक स्थिर है और b> = a)
अतः हर्रे द्वारा कवर की गई अतिरिक्त दूरी = समीकरण 2 - समीकरण 1 = (बीए) * एल है
कृपया ध्यान दें कि यह दूरी भी शुरुआती बिंदु से कछुए की दूरी के बराबर है क्योंकि खरगोश कछुए की तुलना में 2 गुना तेज चलता है। इसे 'म्यू + के' के बराबर किया जा सकता है, जो कि शुरुआत से बैठक बिंदु की दूरी भी है यदि हम चक्र के कई ट्रैवर्स शामिल नहीं करते हैं।
इस प्रकार, म्यू + के = (बा) * एल
तो इस बिंदु से मु कदमों को चक्र की शुरुआत में वापस ले जाया जाएगा (क्योंकि चक्र की शुरुआत से k चरणों को बैठक बिंदु तक पहुंचने के लिए पहले ही ले लिया गया है)। यह उसी चक्र या उसके बाद के किसी भी चक्र में हो सकता है। इस प्रकार अब अगर हम कछुए को लिंक्ड सूची की शुरुआत में ले जाते हैं, तो यह चक्र के शुरुआती बिंदु तक पहुंचने के लिए म्यू कदम उठाएगा और हैर चक्र की शुरुआत तक पहुंचने के लिए म्यू कदम उठाएंगे और इस तरह वे दोनों मिलेंगे चक्र का आरंभ बिंदु।
पीएस ईमानदारी से, मेरे मन में मूल पोस्टर के समान ही प्रश्न था और मैंने पहला उत्तर पढ़ा, उन्होंने कुछ चीजें स्पष्ट कीं लेकिन मैं अंतिम परिणाम तक स्पष्ट रूप से नहीं पहुंच पाया और इसलिए मैंने इसे अपने तरीके से करने की कोशिश की और इसे समझना आसान था।
कॉल एक पॉइंटर के लिंक की संख्या से दूरी तय करता है, और समय पुनरावृत्तियों की संख्या एल्गोरिथ्म धीमी पॉइंटर एक लिंक और फास्ट पॉइंटर दो लिंक को आगे बढ़ाता है। लंबाई C के एक चक्र से पहले N नोड्स हैं, जिन्हें C-1 के माध्यम से चक्र ऑफसेट k = 0 के साथ लेबल किया गया है।
चक्र की शुरुआत तक पहुंचने के लिए, धीमी गति से एन समय और दूरी लेता है। इसका मतलब है कि उपवास चक्र में N की दूरी तय करता है (N वहां पहुंचने के लिए, N से स्पिन करने के लिए)। तो समय N पर, धीमे चक्र ऑफसेट k = 0 पर है, और उपवास चक्र ऑफसेट k = N mod C पर है।
यदि N mod C शून्य है, तो धीमा और तेज अब मेल खाता है और चक्र समय N और चक्र स्थिति k = 0 पर पाया जाता है।
यदि एन मॉड सी शून्य नहीं है, तो उपवास को अब धीमी गति से पकड़ना पड़ता है, जो उस समय चक्र में एन- सी (एन मॉड सी) दूरी है।
चूंकि धीमी गति के प्रत्येक 1 के लिए तेजी से 2 चलता है, इसलिए प्रत्येक पुनरावृत्ति पर दूरी को 1 से कम करना, यह N के समय तेज और धीमी गति के बीच की दूरी के रूप में अधिक अतिरिक्त समय लेता है, जो कि C- (N mod C) है। चूंकि धीमी गति से ऑफसेट 0 से आगे बढ़ रहा है, यह भी ऑफसेट है जहां वे मिलते हैं।
इसलिए, यदि एन मॉड सी शून्य है, तो चक्र की शुरुआत में एन पुनरावृत्तियों के बाद चरण 1 बंद हो जाता है। अन्यथा, चरण 1 N + C- (N mod C) पुनरावृत्तियों के बाद ऑफसेट 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: धीमी गति से चक्र पर जाने के लिए एन अधिक कदम उठाते हैं, जिस बिंदु पर तेजी से (अब 1 प्रति कदम कदम) चल रहा है (सी- (एन मॉड सी) + एन) मॉड सी = 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;
}
समस्या को एक लूप समस्या में कम करें, फिर प्रारंभिक समस्या पर वापस जाएं
मुझे निम्नलिखित स्पष्टीकरण अधिक सहज लगता है।
दो पॉइंटर्स ( 1 = कछुआ और 2 = हेक्टेयर) लें जो सिर से शुरू होते हैं ( O ), 1 की लंबाई 1 है , 2 की लंबाई 2 है । उस पल के बारे में सोचें जब 1 उस चक्र ( ए ) के प्रारंभ नोड तक पहुंचता है ।
हम निम्नलिखित प्रश्न का उत्तर देना चाहते हैं "1 में 2 कहाँ है?" ।
तो, 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
।
दूरी के अंतर्गत आने वाले 1 है d = OA = a = k*n + b
। लेकिन एक ही समय में, 2 कवर D = 2*d = d + d = OA + d = OA + k*n + b
। इसका मतलब है कि जब 2 ए में है तो उसे कवर करना होगाk*n + b
। आप देख सकते हैं, k
लैप की संख्या है, लेकिन उन लैप के बाद, 2 हो जाएगा ख ए तो दूर, हमने पाया है जहां 2 जब है 1 ए लेट्स कॉल उस बिंदु में है B
, जहां AB = b
।
अब, हम एक सर्कल में समस्या को कम करते हैं। प्रश्न "बैठक बिंदु कहाँ है?" । वह C कहां है ?
हर कदम में, २ से दूरी कम कर देता है 1 साथ 1
(आइए कहते मीटर), क्योंकि 1 से आगे हो रही है 2 के साथ 1
, लेकिन एक ही समय में 2 के करीब हो जाता है 1 से 2
।
तो, चौराहा होगा जब बीच की दूरी 1 और 2 के शून्य होगी। इसका मतलब है कि 2n - b
दूरी कम कर देता है । इसे प्राप्त करने के लिए, 1n - b
चरण बनाएगा , जबकि 22*(n - b)
चरण बनाएगा ।
तो, प्रतिच्छेदन बिंदु ए (क्लॉकवाइज) n - b
से दूर होगा , क्योंकि यह 1 से कवर की गई दूरी है जब तक कि यह 2 से पूरा नहीं होता है । => C और A के बीच की दूरी हैCA = b
, क्योंकिAC = AB + BC = n - b
और CA = n - AC
। ऐसा मत सोचो AC = CA
, क्योंकि AC
दूरी एक तुच्छ गणितीय दूरी नहीं है, यह ए और सी के बीच चरणों की संख्या है (जहां ए शुरुआती बिंदु है और सी अंतिम बिंदु है)।
अब, प्रारंभिक स्कीमा पर वापस जाते हैं।
हम जानते हैं कि a = k*n + b
और CA = b
।
हम 2 नए पॉइंटर्स ले सकते हैं 1 ' और 1' ' , जहाँ 1' हेड ( O ) से शुरू होता है और 1 '' इंटरसेक्शन पॉइंट ( C ) से शुरू होता है ।
जबकि 1 ' O से A में जाता है , 1' ' C से A में जाता है और k
लैप्स खत्म करता रहता है । तो, प्रतिच्छेदन बिंदु A है ।
यदि पॉइंटर्स बिंदु P पर मिलते हैं जैसा कि चित्र में दिखाया गया है, तो Z + Y बिंदु P है और X + Y बिंदु P भी है जिसका अर्थ Z = X है। यही कारण है कि P से एक पॉइंटर को आगे रखते हुए और दूसरे को स्टार्ट (S) से तब तक हिलाते रहते हैं जब तक वे मिलते नहीं हैं, जिसका अर्थ है कि समान दूरी (Z या X) से एक ही बिंदु M (M से Z और P से X की दूरी पर) लूप की शुरुआत। सरल!
उपरोक्त सभी विश्लेषणों के साथ, यदि आप एक सीखे हुए व्यक्ति हैं, तो मैंने एक छोटा विश्लेषण और उदाहरण लिखने की कोशिश की, जो गणित को समझाने में मदद करता है बाकी सभी को समझाने का प्रयास किया जाता है। ये रहा!
विश्लेषण:
यदि हमारे पास दो पॉइंटर्स हैं, तो एक दूसरे की तुलना में तेज़ है, और उन्हें एक साथ आगे बढ़ाते हैं, वे अंततः एक चक्र या शून्य को इंगित करने के लिए फिर से मिलेंगे बिना किसी चक्र को इंगित करने के।
चक्र के शुरुआती बिंदु को खोजने के लिए, आइए ...
m
चक्र की शुरुआत में सिर से दूरी;
d
चक्र में नोड्स की संख्या हो;
p1
धीमी सूचक की गति हो;
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
चक्र की शुरुआत से दूर होते हैं । इसे हल करने के लिए, तेज सूचक को वापस सिर पर रखें और धीमी गति से सूचक की गति पर अपनी गति निर्धारित करें। जब वे फिर से मिलते हैं, तो नोड चक्र की शुरुआत है।
हम कहते हैं,
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 स्पीड पर चलता है, B 2x गति पर, दोनों शुरुआत में शुरू होते हैं।
जब A N [0] पर पहुंचता है, B को पहले से ही N [m] में होना चाहिए। (नोट: A, N [0] तक पहुँचने के लिए m चरणों का उपयोग करता है, और B को m कदम आगे होना चाहिए)
फिर, A, B से टकराने के लिए और कदम उठाता है, यानी A, N [k] पर है, B N [m + 2k] पर है (नोट: B को N [m] से शुरू होने वाले 2k चरणों के लिए चलना चाहिए]
क्रमशः N [k] और N [m + 2k] पर एक टकराया B, इसका अर्थ है k = m + 2k, इस प्रकार = m
इस प्रकार, एन [के] से एन [0] पर वापस जाने के लिए, हमें और अधिक चरणों की आवश्यकता है।
सीधे शब्दों में कहें, तो हमें टक्कर के नोड को खोजने के बाद हमें केवल और कदम चलाने की जरूरत है। हमारे पास शुरुआत से चलने के लिए एक पॉइंटर हो सकता है और एक पॉइंटर टक्कर नोड से चल सकता है, वे एम चरणों के बाद एन [0] पर मिलेंगे।
इसलिए, छद्म कोड निम्नानुसार हैं:
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
मुझे नहीं लगता कि यह सच है कि जब वे मिलते हैं तो शुरुआती बिंदु होता है। लेकिन हाँ अगर अन्य पॉइंटर (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;
}
हाई स्कूल में पढ़ाए जाने वाले सापेक्ष वेग के विचार का उपयोग करते हुए एक सरल व्याख्या - भौतिकी 101 / किनेमैटिक्स व्याख्यान।
मान लें कि लिस्ट की शुरुआत से लेकर सर्कल के शुरू होने तक की दूरी x
हॉप्स है। चलो सर्कल की शुरुआत को बिंदु के रूप में कहते हैं X
(कैप्स में - ऊपर आंकड़ा देखें)। यह भी मान लें कि वृत्त का कुल आकार N हॉप्स है।
हरेक की गति = 2 * कछुए की गति। तो वह यह है कि 1 hops/sec
और 2 hops/sec
क्रमश:
जब कछुआ सर्कल की शुरुआत तक पहुंचता है X
, तो हारे को आंकड़े में x
बिंदु पर दूर हॉप्स होना चाहिए Y
। (क्योंकि हरे ने कछुए के रूप में दुगुनी दूरी तय की है)।
इस प्रकार, शेष आर्क की लंबाई X से Y तक की होगी N-x
। T उनकी भी है, जो उनके लिए कछुआ और कछुआ के बीच की दूरी तय करती है, जिससे वे मिल सकें । मान लीजिए कि यह सापेक्ष दूरी समय- t_m
समय पर मिलने के लिए कवर की जाएगी । सापेक्ष गति (2 hops/sec - 1 hops/sec)
अर्थात है 1 hops/sec
। इस प्रकार, सापेक्ष दूरी = सापेक्ष गति X समय, हम प्राप्त करते हैं,t
= N-x
सेकंड। तो यह N-x
कछुआ और खरगोश दोनों के लिए बैठक बिंदु तक पहुंचने के लिए ले जाएगा ।
अब N-x
एकांत समय और 1 hops/sec
गति में, जो कछुआ पहले बिंदु पर था, X
वह बैठक बिंदु तक पहुंचने के लिए Nx हॉप्स को कवर करेगा M
। तो, कि साधन बैठक बिंदु M
पर है N-x
हॉप्स से वामावर्त X
= (जो आगे निकलता है) => है कि वहाँ x
बिंदु से शेष दूरी M
के लिए X
दक्षिणावर्त।
लेकिन लिंक की गई सूची की शुरुआत से x
बिंदु तक पहुंचने की दूरी भी है X
।
अब, हमें परवाह नहीं है कि हॉप्स की संख्या किससे x
मेल खाती है। यदि हम लिंक्डलिस्ट की शुरुआत में एक कछुआ रखते हैं और एक कछुआ बैठक बिंदु पर है M
और उन्हें हॉप / चलने देता है, तो वे बिंदु पर मिलेंगे X
, जो कि बिंदु (या नोड) है जो हमें चाहिए।
इसे आरेख के साथ काम करने से मदद मिलेगी। मैं समीकरणों के बिना समस्या को समझाने की कोशिश कर रहा हूं।
- लूप से पहले k कदम हैं। हम नहीं जानते कि k क्या है और इसका पता लगाने की आवश्यकता नहीं है। हम सिर्फ k के साथ अमूर्त रूप से काम कर सकते हैं।
- के बाद कदम
----- T चक्र की शुरुआत में है
----- H चक्र में k कदम है (वह कुल 2 k गया और इस प्रकार k लूप में है)
** वे अब कर रहे हैं - कश्मीर के अलावा
(ध्यान दें कि k == K == mod (loopsize, k) - अगर एक नोड 5 चरण में 2 चरण है, तो यह 7, 12 या 392 चरणों में भी है, इसलिए चक्र कितना बड़ा है k k नहीं में कारक।
चूँकि वे एक-दूसरे के प्रति 1 कदम की दर से एक-दूसरे को पकड़ते हैं क्योंकि एक दूसरे की तुलना में दोगुना गति से आगे बढ़ रहा है, वे छोरों - के पर मिलेंगे।
इसका मतलब यह है कि चक्र की शुरुआत तक पहुंचने के लिए यह k नोड्स लेगा और इस प्रकार सिर से चक्रवात की दूरी और चक्रवात से टकराव समान होते हैं।
तो अब पहली टक्कर के बाद टी वापस सिर की ओर बढ़ते हैं। यदि आप प्रत्येक 1 की दर से चलते हैं तो T और H चक्रवात में मिलेंगे। (दोनों के लिए k चरणों में)
इसका मतलब है कि एल्गोरिथ्म है:
// मामले का ख्याल रखें जब k = 0 या T और H लूप की लंबाई की गणना करके लूप के सिर पर मिले
- एक काउंटर के साथ टी या एच को घुमाकर चक्र की लंबाई को बढ़ाएं
- सूची के प्रमुख के लिए एक सूचक T2 को हटाएं
- चक्र चरणों की पॉइंटर लंबाई की लंबाई
- एक और पॉइंटर H2 को सिर पर रखें
- टी 2 और एच 2 को अग्रानुक्रम में मिलाएं जब तक कि वे चक्र की शुरुआत में नहीं मिलते
बस!
इसके लिए पहले से ही बहुत सारे उत्तर हैं, लेकिन मैं एक बार इसके लिए एक आरेख लेकर आया हूं जो मेरे लिए अधिक नेत्रहीन है। शायद यह अन्य लोगों की मदद कर सकता है।
मेरे लिए मुख्य अहा क्षण थे:
मुझे पता है कि इस समस्या के लिए पहले से ही एक स्वीकृत जवाब है, लेकिन मैं अभी भी तरल तरीके से जवाब देने की कोशिश करूंगा। मान लीजिये :
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.
अब, शुरू से ही 'टी' के बाद हरे और कछुए को मिलने दें।
टिप्पणियों:
यदि, कछुआ = v * t = x + (bk) (दूरी) द्वारा यात्रा की गई दूरी
फिर, दूरी को हरे = 2 * v * t = x + (b - k) + b से तय किया जाता है (क्योंकि खरगोश ने पहले ही एक बार लूप किए गए हिस्से को ट्रेस कर लिया है)
अब, बैठक के समय समान हैं।
=> x + 2 * b - k = 2 * (x + b - k)
=> एक्स = के
यह निश्चित रूप से इसका अर्थ है कि जिस मार्ग की लूपिंग नहीं की गई है, वह दोनों मिलने वाले बिंदु से लूप के शुरुआती बिंदु की दूरी के समान है।
यह साबित करना आसान है कि वे दोनों प्रारंभिक बिंदु पर मिलेंगे, यदि आप बैठक बिंदु के पीछे के गणित पर विचार करते हैं।
सबसे पहले जाने मीटर लिंक्ड सूची में चक्र के प्रारंभिक बिंदु निरूपित, और एन चक्र की लंबाई को दर्शाते हैं। फिर मिलने के लिए हर्रे और कछुए के लिए:
( 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-m) modulo n = (0-m) modulo n = (-m) modulo n
।
तो अब प्रश्न पर वापस आते हैं, यदि आप एक पॉइंटर को लिंक्ड लिस्ट की शुरुआत से आगे बढ़ाते हैं, और दूसरे को चौराहे के बिंदु से, एम स्टेप्स के बाद हमारे पास हैरे (जो चक्र के अंदर जा रहा है) एक बिंदु पर आ जाता है जो है ((-m) + m) modulo n = 0 modulo n
जो कि चक्र के शुरुआती बिंदु के अलावा कुछ भी नहीं है। इसलिए हम देख सकते हैं कि मी चरणों के बाद यह चक्र की शुरुआत में आता है और कछुआ इसे वहां मिल जाएगा क्योंकि यह लिंक की गई सूची की शुरुआत से मी कदमों को पीछे कर देगा ।
एक साइड नोट के रूप में, हम उनके प्रतिच्छेदन के समय की गणना इस तरह से भी कर सकते हैं: स्थिति t = 0 modulo n
हमें बताती है कि वे एक समय में मिलेंगे, जो कि कई चक्र की लंबाई है, और t को m से अधिक होना चाहिए , क्योंकि वे में मिलेंगे साईकिल । तो समय पहले n के पहले बहु के बराबर होगा जो m से बड़ा है ।
मान लीजिए कि आपके संकेत बिंदु y और z के चौराहे पर मिलते हैं।
एन और मी तेजी से छोरों की संख्या हैं और धीमी सूचक बैठक से पहले क्रमशः लेते हैं।
शेष प्रमाण के लिए छवि देखें। लिंक की गई सूची में लूप का प्रारंभिक बिंदु खोजें