परिचय
यहाँ एक संभव समाधान है। यह बल्कि विकसित है और व्यावहारिक नहीं है, लेकिन फिर भी समस्या है। अगर मेरे विश्लेषण में छेद है तो मैं किसी भी टिप्पणी की सराहना करता हूं। अगर यह एक "आधिकारिक" समाधान के साथ होमवर्क या चुनौती समस्या थी, तो मुझे यह भी देखना अच्छा लगेगा कि मूल पोस्टर अभी भी इसके बारे में है, क्योंकि यह पूछे जाने के बाद एक महीने से अधिक समय बीत चुका है।
सबसे पहले, हमें समस्या के कुछ अस्पष्ट विवरणों को दूर करने की आवश्यकता है। समय जटिलता O(N)
है, लेकिन N
क्या है? अधिकांश टिप्पणीकार मानते हैं कि N
सरणी में तत्वों की संख्या है। यह ठीक होगा अगर सरणी में संख्याएं अधिकतम आकार के निश्चित थीं, इस मामले में माइकल जी का रेडिक्स सॉर्ट का समाधान समस्या को हल करेगा। लेकिन, मैं मूल पोस्टर द्वारा स्पष्टीकरण की अनुपस्थिति में बाधा # 1 की व्याख्या करता हूं, क्योंकि कहता है कि अंकों की अधिकतम संख्या तय नहीं की जानी चाहिए। इसलिए, यदि n
(लोअरकेस) सरणी में तत्वों की संख्या है, और औसत तत्वों की लंबाई है, तो कुल इनपुट आकार mn
के साथ संघर्ष करने के लिए है। समाधान समय पर कम बाध्य O(mn)
है क्योंकि यह समाधान को सत्यापित करने के लिए आवश्यक इनपुट का रीड-थ्रू टाइम है। इसलिए, हम एक समाधान चाहते हैं जो कुल इनपुट आकार N = nm
के संबंध में रैखिक है।
उदाहरण के लिए, हम n = m
हो सकता है, कि sqrt(N)
औसत लंबाई के sqrt(N)
तत्वों है। तुलनात्मक प्रकार O(log(N) sqrt(N)) < O(N)
संचालन लेगा, लेकिन यह एक जीत नहीं है, क्योंकि ऑपरेशन औसत पर O(m) = O(sqrt(N))
समय लेते हैं, इसलिए हम O(N log(N))
पर वापस आ गए हैं।
इसके अलावा, एक मूलांक तरह O(mn) = O(N)
ले m
औसत लंबाई के बजाय अधिकतम लंबाई होने पर होता। अधिकतम और औसत लंबाई उसी क्रम पर होगी यदि संख्याओं को कुछ सीमाबद्ध सीमा में गिरने के लिए माना जाता था, लेकिन यदि नहीं, तो हमारे पास अंकों की एक बड़ी और परिवर्तनीय संख्या के साथ एक छोटा प्रतिशत हो सकता है और अंकों की एक छोटी संख्या के साथ एक बड़ा प्रतिशत हो सकता है । उदाहरण के लिए, संख्याओं का 10% लंबाई m^1.1
और 90% लंबाई m*(1-10%*m^0.1)/90%
हो सकता है। औसत लंबाई m
होगी, लेकिन अधिकतम लंबाई m^1.1
है, इसलिए रेडिक्स सॉर्ट O(m^1.1 n) > O(N)
होगा।
अगर कोई समस्या है कि मैंने समस्या परिभाषा को नाटकीय रूप से बदल दिया है, तो मेरा लक्ष्य अभी भी O(n)
तत्वों की संख्या के लिए समय जटिलता के साथ एक एल्गोरिदम का वर्णन करना है। लेकिन, मुझे प्रत्येक तत्व की लंबाई पर रैखिक समय जटिलता के संचालन करने की भी आवश्यकता होगी, ताकि सभी तत्वों के औसत पर ये ऑपरेशन O(m)
हो। तत्वों और तुलनाओं पर हैश कार्यों की गणना करने के लिए उन परिचालनों में गुणा और अतिरिक्त आवश्यकता होगी। और यदि वास्तव में यह समाधान O(N) = O(nm)
में समस्या हल करता है, तो यह इष्टतम जटिलता होनी चाहिए क्योंकि उत्तर को सत्यापित करने के लिए एक ही समय लगता है।
समस्या परिभाषा से छोड़ा गया एक अन्य विवरण यह है कि हमें डेटा को नष्ट करने की अनुमति है क्योंकि हम इसे संसाधित करते हैं। मैं सादगी के लिए ऐसा करने जा रहा हूं, लेकिन मुझे लगता है कि अतिरिक्त देखभाल के साथ इसे टाला जा सकता है।
संभव समाधान
पहले, बाधा वहाँ नकारात्मक संख्या हो सकता है कि एक खाली एक है। डेटा के माध्यम से एक पास के साथ, हम न्यूनतम तत्व, z
, और तत्वों की संख्या, n
रिकॉर्ड करेंगे। दूसरे पास पर, हम प्रत्येक तत्व में (3-z)
जोड़ देंगे, इसलिए सबसे छोटा तत्व अब 3 है। (ध्यान दें कि परिणामों की निरंतर संख्या परिणामस्वरूप बहती जा सकती है, इसलिए हमें पहले डेटा के माध्यम से अतिरिक्त पास की निरंतर संख्या करना चाहिए इन समाधानों के लिए परीक्षण करें।) एक बार हमारे पास समाधान होने के बाद, हम इसे अपने मूल रूप में वापस करने के लिए (3-z)
घटाते हैं। अब हमारे पास तीन विशेष मार्कर मान 0
, 1
, और 2
उपलब्ध हैं, जो स्वयं तत्व नहीं हैं।
चरण 1
median-of-medians selection algorithm का उपयोग 90 प्रतिशत तत्व, p
निर्धारित करने के लिए, सरणी A
की और सेट दो सेट S
और T
में सरणी विभाजन जहां S
p
और T
से अधिक 10% of n
तत्व है p
से कम तत्व हैं। यह O(n)
चरणों (O(N)
कुल) के औसत पर O(m)
ले जाने के चरणों के साथ लेता है। p
से मिलान करने वाले तत्वों को या तो S
या T
में रखा जा सकता है, लेकिन सादगी के लिए, एक बार सरणी के माध्यम से चलाएं और p
का परीक्षण करें और 0
के साथ इसे बदलकर इसे खत्म करें।S
मूल रूप से इंडेक्स 0..s
स्पैन करता है, जहां s
n
है, और T
सेट करें शेष 90% इंडेक्स s+1..n
पर फैलाएं।
चरण 2
अब हम i in 0..s
लूप करने के लिए जा रहे हैं और प्रत्येक तत्व e_i
के लिए हम s+1..n
में एक हैश समारोह h(e_i)
गणना करने के लिए जा रहे हैं। समान वितरण प्राप्त करने के लिए हम universal hashing का उपयोग करेंगे। तो, हमारे हैशिंग फ़ंक्शन गुणा और जोड़ करेंगे और इसकी लंबाई के संबंध में प्रत्येक तत्व पर रैखिक समय लेंगे।
हम टकराव के लिए एक संशोधित रैखिक जांच कर रणनीति का उपयोग करेंगे:
h(e_i)
T
के एक सदस्य के कब्जे में है (A[ h(e_i) ] < p
अर्थ लेकिन एक मार्कर 1
या 2
नहीं है) या 0
है। यह एक हैश टेबल मिस है। स्लॉट i
और h(e_i)
से तत्वों को स्वैप करके e_i
डालें।
h(e_i)
S
(जिसका अर्थ है A[ h(e_i) ] > p
) के एक सदस्य या मार्कर 1
या 2
के कब्जे में है। यह एक हैश टेबल टकराव है। e_i
या T
या 0
के सदस्य का डुप्लिकेट होने तक रैखिक जांच करें।
T
के एक सदस्य है, यह एक फिर से एक हैश तालिका याद आती है, तो i
स्लॉट को स्वैप करके e_i
(1.)
में के रूप में सम्मिलित करें।
यदि e_i
का डुप्लिकेट है, तो यह हैश तालिका हिट है। अगले तत्व की जांच करें। यदि वह तत्व 1
या 2
है, तो हमने e_i
को पहले से कहीं अधिक देखा है, 1
एस 2
एस में बदलें और इसके विपरीत समानता में इसके परिवर्तन को ट्रैक करने के लिए। यदि अगला तत्व 1
या 2
नहीं है, तो हमने केवल एक बार पहले e_i
देखा है। हम को अब भी कई बार देख चुके हैं, यह इंगित करने के लिए हम 2
को अगले तत्व में संग्रहीत करना चाहते हैं। हम अगले "खाली" स्लॉट के लिए देखो, कि एक T
के एक सदस्य है जो हम स्लॉट i
, या एक 0 में चले जाएंगे, और तत्वों वापस शिफ्ट सूचकांक h(e_i)+1
नीचे से ऊपर तो हम करने के लिए h(e_i)
के बगल में कमरा है के कब्जे में है हमारी समानता जानकारी स्टोर करें। ध्यान दें कि हमें e_i
को फिर से स्टोर करने की आवश्यकता नहीं है, इसलिए हमने कोई अतिरिक्त स्थान नहीं उपयोग किया है।
तो बुनियादी तौर पर हम साथ एक कार्यात्मक हैश तालिका है 9 गुना तत्वों हम हैश करने के लिए इच्छा के रूप में स्लॉट की संख्या। एक बार जब हम हिट प्राप्त करना शुरू कर देते हैं, तो हम समानता की जानकारी भी संग्रहित करना शुरू करते हैं, इसलिए हम केवल 4.5 गुना संख्या स्लॉट के साथ समाप्त हो सकते हैं, फिर भी बहुत कम लोड फैक्टर। ऐसी कई टकराव रणनीतियों हैं जो यहां काम कर सकती हैं, लेकिन चूंकि हमारा लोड कारक कम है, इसलिए टकराव की औसत संख्या भी कम होनी चाहिए और रैखिक जांच उन्हें औसतन उपयुक्त समय जटिलता के साथ हल करनी चाहिए।
चरण 3
एक बार जब हम s+1..n
में 0..s
के तत्वों hashing समाप्त हो गया है, हम s+1..n
बढ़ावा देते हैं। अगर हमें 2
के बाद एस का तत्व मिलता है, तो यह हमारा लक्ष्य तत्व है और हम कर रहे हैं। के e
के बाद कोई भी तत्व S
का एक और तत्व इंगित करता है e
केवल एक बार सामना किया गया था और इसे शून्य किया जा सकता है। इसी तरह e
के बाद 1
का अर्थ है कि हमने e
को कई बार देखा, और हम e
और मार्कर 1
को शून्य कर सकते हैं।
रिंस और के रूप में वांछित
हम अपने लक्ष्य तत्व नहीं मिला है, तो हम प्रक्रिया को दोहराने दोहराएँ। हमारा 90 वां प्रतिशत विभाजन n
A
की शुरुआत में शेष सबसे बड़े तत्वों को छोड़ देगा और शेष 0
-मार्कर स्लॉट समेत शेष तत्वों को अंत में ले जाएगा। हम पहले से ही हैशिंग के साथ जारी है। हमें इसे हर बार 10 बार करना है क्योंकि हम हर बार n
का 10% संसाधित करते हैं।
मंझला के- माध्यिकाओं एल्गोरिथ्म के माध्यम से समापन विश्लेषण
विभाजन O(N)
के समय जटिलता है, जो हम 10 बार, अभी भी O(N)
करना है। हैश टेबल लोड कम होने के बाद प्रत्येक हैश ऑपरेशन O(1)
लेता है और हैश ऑपरेशंस कुल प्रदर्शन (10 पुनरावृत्ति में से प्रत्येक के लिए लगभग 10% एन) किया जाता है। n
तत्वों में से प्रत्येक के लिए उनके पास गणना की गई हैश फ़ंक्शन है, समय की जटिलता उनकी लंबाई के लिए रैखिक है, इसलिए O(m)
सभी तत्वों पर औसत पर। इस प्रकार, कुल मिलाकर हैशिंग ऑपरेशन O(mn) = O(N)
हैं। इसलिए, अगर मैंने इसका सही ढंग से विश्लेषण किया है, तो पूरे पर इस एल्गोरिदम O(N)+O(N)=O(N)
है। (यह O(n)
भी है यदि अतिरिक्त, गुणा, तुलना, और स्वैपिंग के संचालन इनपुट के संबंध में निरंतर समय माना जाता है।)
ध्यान दें कि यह एल्गोरिदम समस्या परिभाषा की विशेष प्रकृति का उपयोग नहीं करता है कि केवल एक तत्व घटनाओं की एक संख्या भी है। हमने समस्या की इस विशेष प्रकृति का उपयोग नहीं किया है परिभाषा पत्तियां इस संभावना को खोलती हैं कि एक बेहतर (अधिक चालाक) एल्गोरिदम मौजूद है, लेकिन अंत में यह ओ (एन) भी होना चाहिए।
नहीं, यह नहीं होगा। काउंटर उदाहरण देखें: '[1,1,1,5,2,2]'। 1 एक्सओआर 1 एक्सओआर 1 एक्सओआर 5 एक्सओआर 2 एक्सओआर 2 == 001^001^001^101^010^010 == 100 – amit
जटिलता के बारे में निश्चित नहीं है, लेकिन आपके पास दो हैश-सेट नहीं हो सकते हैं, जिसमें आप स्टोर करते हैं सभी * देखी गई * संख्याएं, और एक जिसमें आप पहली बार इसे देखते हुए पहली बार स्टोर करते हैं, दूसरी बार इसे देखते हुए इसे हटा दें और इसी तरह। अंत में आपके पास सभी संख्याओं के साथ एक सेट (ए) होगा, और एक सेट (बी) सभी विषम-संख्याओं के साथ होगा। इसके बाद आपको (ए) से (ए) रैखिक समय में घटाना चाहिए, जिससे परिणाम प्राप्त करना चाहिए। (हालांकि यह एक उपयुक्त हैश फ़ंक्शन मानता है।) -: – aioobe
@aioobe: मुझे विश्वास है कि "जगह में" ओपी 'ओ (1) 'स्पेस समाधान की तलाश में है। (अन्यथा एक साधारण हिस्टोग्राम और फिर इसे फिर से करना होगा) – amit