कैफ़े का शानदार उत्तर प्रत्येक संख्या को प्रिंट करता है जो कि सरणी के -१ में k बार दिखाई देता है। यह उपयोगी व्यवहार है, लेकिन सवाल यकीनन प्रत्येक डुप्लिकेट को केवल एक बार मुद्रित करने के लिए कहता है, और वह रैखिक समय / निरंतर अंतरिक्ष सीमा को उड़ाने के बिना ऐसा करने की संभावना के लिए संकेत देता है। यह निम्नलिखित छद्मकोश के साथ अपने दूसरे लूप को बदलकर किया जा सकता है:
for (i = 0; i < N; ++i) {
if (A[i] != i && A[A[i]] == A[i]) {
print A[i];
A[A[i]] = i;
}
}
यह उस संपत्ति का शोषण करता है जो पहले लूप के चलने के बाद, यदि कोई मूल्य mएक से अधिक बार दिखाई देता है, तो उन दिखावे में से एक को सही स्थिति में होने की गारंटी दी जाती है, अर्थात् A[m]। यदि हम सावधान रहें तो हम उस "घर" स्थान का उपयोग कर सकते हैं ताकि किसी डुप्लिकेट को अभी तक मुद्रित किया गया है या नहीं, इस बारे में जानकारी संग्रहीत करने के लिए।
कैफे के संस्करण में, जैसा कि हम सरणी के माध्यम से गए थे, A[i] != iनिहित है कि A[i]एक डुप्लिकेट है। मेरे संस्करण में, मैं थोड़ा अलग अपरिवर्तनीय पर भरोसा करता हूं: A[i] != i && A[A[i]] == A[i]इसका मतलब है कि A[i]एक डुप्लिकेट है जो हमने पहले नहीं देखा है । (यदि आप "वह जिसे हमने पहले नहीं देखा है" भाग में छोड़ देते हैं, तो बाकी को कैफ़े के अपरिवर्तनीय की सच्चाई से निहित होने के लिए देखा जा सकता है, और गारंटी है कि सभी डुप्लिकेट के पास एक घर के स्थान में कुछ कॉपी है।) शुरू (कैफे के 1 लूप खत्म होने के बाद) और मैं नीचे दिखाता हूं कि यह प्रत्येक चरण के बाद बनाए रखा जाता है।
जैसा कि हम सरणी से गुजरते हैं, A[i] != iपरीक्षण के हिस्से पर सफलता का मतलब है कि एक डुप्लिकेट A[i] हो सकता है जो पहले नहीं देखा गया है। यदि हमने इसे पहले नहीं देखा है, तो हम A[i]अपने आप को इंगित करने के लिए घर के स्थान की अपेक्षा करते हैं - यही ifस्थिति की दूसरी छमाही तक परीक्षण किया जाता है । अगर ऐसा है, तो हम इसे प्रिंट करते हैं और घर का स्थान बदलकर इस पहले पाए गए डुप्लिकेट को वापस इंगित करते हैं, जिससे 2-चरण "चक्र" बनता है।
यह देखने के लिए कि यह ऑपरेशन हमारे आक्रमणकारी को परिवर्तित नहीं करता है, मान लीजिए कि वह m = A[i]किसी विशेष स्थिति के लिए iसंतोषजनक है A[i] != i && A[A[i]] == A[i]। यह स्पष्ट है कि हम जो परिवर्तन करते हैं ( A[A[i]] = i) अन्य गैर-घरेलू घटनाओं को mआउटपुट के रूप में डुप्लिकेट होने से रोकने के लिए काम करेंगे, जिससे उनकी ifस्थिति का 2 आधा हिस्सा विफल हो जाएगा, लेकिन क्या यह iघर के स्थान पर आने पर काम करेगा m? हां यह होगा, क्योंकि अब, भले ही इस नए पर iहम पाते हैं कि ifहालत का 1 आधा हिस्सा A[i] != i, सच है, 2 आधा परीक्षण है कि क्या यह जिस स्थान को इंगित करता है वह एक घर का स्थान है और पाता है कि यह नहीं है। इस स्थिति में हम नहीं जानते कि डुप्लिकेट मान था mया नहीं A[m], लेकिन हम जानते हैं कि दोनों ही तरह से,यह पहले ही रिपोर्ट किया जा चुका है , क्योंकि इन 2-चक्रों को कैफे के 1 लूप के परिणाम में प्रदर्शित नहीं होने की गारंटी है। (ध्यान दें कि यदि m != A[m]तब वास्तव में से एक mऔर A[m]एक बार से अधिक होता है, और अन्य सभी पर नहीं होती है।)
a[a[i]], औरswap()ऑपरेशन में ओ (1) अंतरिक्ष बाधा संकेत प्रमुख है।