ओ (एन) समय में 5 दोहराया मूल्यों को कैसे खोजें?


15

मान लीजिए कि आपके पास से तक पूर्णांक के साथ आकार का एक सरणी है , जिसमें समावेशी है। मुझे एक एल्गोरिथ्म का प्रस्ताव करने की आवश्यकता है जो समय में दोहराया संख्याओं का पता लगा सके । मैं, मेरे जीवन के लिए, कुछ भी नहीं सोच सकता। मुझे लगता है कि, सबसे अच्छा, ? फिर सरणी को ट्रेस करना , जिसके परिणामस्वरूप । हालाँकि, मुझे वास्तव में यकीन नहीं है कि अगर छँटाई आवश्यक होगी क्योंकि मैंने लिंक की गई सूची, कतारों, ढेरों आदि के साथ कुछ मुश्किल सामान देखा है।1 एन - 5 हे ( एन ) हे ( एन लॉग इन करें n ) हे ( एन ) हे ( एन 2 लॉग n )n61n5O(n)O(nlogn)O(n)O(n2logn)


16
O ( n 2 log n ) O ( n log n ) O ( n 2 log n )O(nlogn)+O(n) नहीं है । यह । यदि आप ने n बार ऐसा किया तो यह होगा। O(n2logn)O(nlogn)O(n2logn)
निधि मोनिका का मुकदमा


1
@leftaroundabout ये एल्गोरिदम जहाँ सरणी का आकार है और इनपुट सेट का आकार है। चूंकि ये एल्गोरिदम में काम करते हैंn कश्मीर कश्मीर = n - सी एन एस टी एक एन टी ( n 2 )O(kn)nkk=nconstantO(n2)
रोमन ग्रैफ़

4
@ RomanGräf ऐसा प्रतीत होता है कि वास्तविक स्थिति यह है: एल्गोरिदम , जहां डोमेन का आकार है। तो, ओपी की तरह एक समस्या के लिए, यह उसी के लिए नीचे आता है कि क्या आप आकार वाले डोमेन पर इस तरह के एक एल्गोरिथ्म का उपयोग करते हैं , या एक पारंपरिक आकार के डोमेन पर एक पारंपरिक एल्गोरिथ्म। समझ में भी आता है। O(logkn)knO(nlogn)
लेफ्टनैबाउट

5
के लिए , केवल स्वीकृत संख्या है अपने विवरण से,। लेकिन फिर को छह नहीं, पांच बार दोहराना होगा। n=611
एलेक्स रिंकिंग

जवाबों:


22

आप आकार अतिरिक्त सरणी बना सकते हैं । प्रारंभ में सरणी के सभी तत्वों को सेट करें । फिर इनपुट सरणी माध्यम से लूप करें और प्रत्येक लिए को 1 से बढ़ाएं । उसके बाद आप बस : पर लूप और अगर चेक करते हैं, तो दोहराया जाता है। आप इसे समय में मेमोरी की लागत पर हल करते हैं जो और क्योंकि आपके पूर्णांक और बीच हैं ।B0 बी [ एक [ मैं ] ] मैं बी बी [ एक [ मैं ] ] > 1 [ मैं ] हे ( एन ) हे ( एन ) 1 एन - 5n0AB[A[i]]iBAB[A[i]]>1A[i]O(n)O(n)1n5


26

Fade2black के उत्तर में समाधान मानक एक है, लेकिन यह स्थान का उपयोग करता है। आप इसे O ( 1 ) स्थान में निम्नानुसार सुधार सकते हैं:O(n)O(1)

  1. सरणी । के लिए = 1 , ... , 5 , गणना σ = Σ n मैं = 1[ मैं ] A[1],,A[n]d=1,,5σd=i=1nA[i]d
  2. कंप्यूट (आप में बाद राशि की गणना करने के जाने-माने सूत्रों का उपयोग कर सकते हैं हे ( 1 ) )। ध्यान दें कि τ = मीटर 1 + + मीटर 5 , जहां मीटर 1 , ... , मी 5 बार-बार नंबर दिए गए हैं।τd=σdi=1n5idO(1)τd=m1d++m5dm1,,m5
  3. बहुपद कंप्यूट । इस बहुपद के गुणांकों के सममित कार्य हैं मीटर 1 , ... , मी 5 जहाँ से गणना की जा सकती τ 1 , ... , τ 5 में हे ( 1 )P(t)=(tm1)(tm5)m1,,m5τ1,,τ5O(1)
  4. सभी n - 5 संभावनाओं की कोशिश करके बहुपद की सभी जड़ों का पता लगाएं ।P(t)n5

यह एल्गोरिथ्म रैम मशीन मॉडल को मानता है, जिसमें पर मूल अंकगणितीय संचालन ( 1 ) समय लेते हैं ।O(logn)O(1)


इस समाधान को तैयार करने का दूसरा तरीका निम्नलिखित पंक्तियों के साथ है:

  1. गणना , और अनुमान y 1 = m 1 + + मी 5 सूत्र का उपयोग कर y 1 = एक्स 1 - Σ n - 5 मैं = 1 मैंx1=i=1nA[i]y1=m1++m5y1=x1i=1n5i
  2. गणना में हे ( एन ) सूत्र का उपयोग कर एक्स 2 = ( एक [ 1 ] ) एक [ 2 ] + ( एक [ 1 ] + एक [ 2 ] ) [ ] + ( [ १]x2=1i<jA[i]A[j]O(n)
    x2=(A[1])A[2]+(A[1]+A[2])A[3]+(A[1]+A[2]+A[3])A[4]++(A[1]++A[n1])A[n].
  3. अनुमान सूत्र का उपयोग कर y 2 = एक्स 2 - Σ 1 मैं < j n - 5 मैं j - ( n - 5 Σ मैं = 1 मैं ) y 1y2=1i<j5mimj
    y2=x21i<jn5ij(i=1n5i)y1.
  4. गणना करें और समान लाइनों के साथ वाई 3 , वाई 4 , वाई 5 घटाएं।x3,x4,x5y3,y4,y5
  5. के मूल्यों (साइन अप करने के) बहुपद के गुणांकों हैं पी ( टी ) पूर्ववर्ती समाधान से।y1,,y5P(t)

यह समाधान दिखाता है कि यदि हम 5 को बदलते हैं , तो हमें O ( d 2 ) स्पेस का उपयोग करके एक O ( d 2 n ) एल्गोरिथ्म मिलता है, जो कि बिट-लंबाई O के पूर्णांक पर O ( d n ) अंकगणितीय संचालन करता है। ( d log n ) , किसी भी समय इनमें से अधिकांश O ( d ) को रखते हुए । (इसके लिए हमारे द्वारा किए जाने वाले गुणन के सावधानीपूर्वक विश्लेषण की आवश्यकता होती है, जिनमें से अधिकांश में केवल O ( लॉग एन) लंबाई का एक ऑपरेंड शामिल होता हैdO(d2n)O(d2)O(dn)O(dlogn)O(d) ।) यह बोधगम्य है कि इसेमॉड्यूलर अंकगणित का उपयोग करके( डी एन ) समय और( डी ) अंतरिक्ष मेंसुधार किया जा सकता है।O(logn)O(dn)O(d)


का कोई भी व्याख्या और τ , पी ( टी ) , m मैं और इतने पर? क्यों d { 1 , 2 , 3 , 4 , 5 } ? σdτdP(t)mid{1,2,3,4,5}
स्टायरोफोम

3
समाधान के पीछे की अंतर्दृष्टि योग की चाल है , जो कई अभ्यासों में प्रकट होती है (उदाहरण के लिए, आप लंबाई की एक सरणी से लापता तत्व को कैसे खोजते हैं - जिसमें सभी संख्याओं में से एक है, लेकिन संख्या 1 , , n ?)। संक्षेप चाल गणना करने के लिए इस्तेमाल किया जा सकता ( मीटर 1 ) + + ( मीटर 5 ) एक मनमाना कार्य के लिए , और सवाल जो है क्रम में अनुमान करने में सक्षम होने का चयन करने के लिए मीटर 1 , ... , मीटरn11,,nf(m1)++f(m5)ff । मेरा जवाब सममितीय कार्यों के प्राथमिक सिद्धांत से परिचित चाल का उपयोग करता है। m1,,m5
युवल फिल्मस Yu

1
@hoffmale वास्तव में, O(d2)
युवल फिल्मस २०

1
@hoffmale उनमें से प्रत्येक मशीन शब्द लेता है । d
युवल फिल्मस

1
@BurnsBA इस दृष्टिकोण के साथ समस्या यह है कि की तुलना में बहुत बड़ा है ( n - 4 ) ( n - 5 )(n5)# । बड़ी संख्या में संचालन धीमा है। (n4)(n5)2
युवल फिल्मस

8

विभाजन के आधार पर एक रेखीय समय और निरंतर स्थान एल्गोरिथ्म भी है, जो अधिक लचीला हो सकता है यदि आप इसे इस समस्या के वेरिएंट पर लागू करने की कोशिश कर रहे हैं कि गणितीय दृष्टिकोण अच्छी तरह से काम नहीं करता है। इसके लिए अंतर्निहित सरणी को बदलने की आवश्यकता होती है और गणितीय दृष्टिकोण की तुलना में लगातार खराब कारक होते हैं। विशेष रूप से, मैं मानों की कुल संख्या के मामले में लागत का मानना है कि और डुप्लिकेट की संख्या d हैं हे ( एन लॉग ) और हे ( ) क्रमशः, हालांकि साबित यह कड़ाई से इस समय अधिक समय की तुलना में मेरे पास ले जाएगा ।ndO(nlogd)O(d)


कलन विधि

जोड़े की एक सूची के साथ शुरू करें, जहां पहली जोड़ी पूरे सरणी पर सीमा है, या यदि 1-अनुक्रमित है।[(1,n)]

सूची खाली होने तक निम्नलिखित चरणों को दोहराएं:

  1. सूची से किसी भी जोड़ी को निकालें और निकालें ।(i,j)
  2. न्यूनतम और अधिकतम, और अधिकतम , निरूपित उपप्रकार का पता लगाएं ।minmax
  3. यदि , सबर्रे में केवल समान तत्व होते हैं। एक को छोड़कर इसके तत्वों को ढालें ​​और चरण 4 से 6 को छोड़ें।min=max
  4. यदि , तो सबर्रे में कोई डुप्लिकेट नहीं है। चरण 5 और 6 छोड़ें।maxmin=ji
  5. न्यूनतम + अधिकतम के आसपास के विभाजन का विभाजन , ऐसे कि कुछ सूचकांकk तक केतत्व विभाजक से छोटे हैं और उस सूचकांक से ऊपर के तत्व नहीं हैं।min+max2k
  6. सूची में जोड़ें और ( k + 1 , j )(i,k)(k+1,j)

समय जटिलता का सरसरी विश्लेषण।

चरण 1 से 6 तक समय लेते हैं , क्योंकि न्यूनतम और अधिकतम और विभाजन को रैखिक समय में खोजा जा सकता है।O(ji)

सूची में प्रत्येक जोड़ी या तो पहली जोड़ी है, ( 1 , n ) , या किसी जोड़ी का एक बच्चा है जिसके लिए संबंधित उपप्रकार में एक डुप्लिकेट तत्व है। ज्यादा से ज्यादा कर रहे हैं लोग इन 2 n + 1 ऐसे माता-पिता, प्रत्येक ट्रेवर्सल हिस्सों जिसमें सीमा एक नकली हो सकता है के बाद से, इसलिए वहाँ ज्यादा से ज्यादा कर रहे हैं 2 लोग इन 2 n + 1 कुल जब कोई साथ subarrays से अधिक जोड़े सहित डुप्लिकेट। किसी भी समय, सूची का आकार 2 डी से अधिक नहीं है(i,j)(1,n)dlog2n+12dlog2n+12d

किसी एक डुप्लिकेट को खोजने के लिए काम पर विचार करें। इसमें एक क्रमिक रूप से घटने वाली सीमा से अधिक जोड़े का क्रम होता है, इसलिए कुल कार्य ज्यामितीय अनुक्रम या का योग होता है । यह एक स्पष्ट कोरोलरी बनाता है कि डी डुप्लिकेट के लिए कुल काम ( एन डी ) होना चाहिए , जो एन में रैखिक है ।O(n)dO(nd)n

एक तंग बाउंड को खोजने के लिए, डुप्लिकेट को अधिकतम रूप से फैलाने के सबसे खराब स्थिति पर विचार करें। सहज रूप से, खोज में दो चरण होते हैं, एक जहां पूर्ण सरणी को हर बार उत्तरोत्तर छोटे भागों में ट्रेस किया जाता है, और एक वह भाग जहां n से छोटे होते हैं इसलिए केवल सरणी के कुछ हिस्सों को ट्रेस किया गया है। पहला चरण केवलडी डीलॉगकिया जा सकता है, इसलिए(एनलॉगडी)खर्च किया गया है, और दूसरे चरण में(एन)लागत है,क्योंकि खोजे जा रहे कुल क्षेत्र में फिर से तेजी से कमी आ रही है।ndlogdO(nlogd)O(n)


विवरण के लिए आपका धन्यवाद। अब मुझे समझ आई। एक बहुत सुंदर एल्गोरिथ्म!
डीडब्ल्यू

5

इसे एक उत्तर के रूप में छोड़ना क्योंकि यह एक टिप्पणी देता है की तुलना में अधिक स्थान की आवश्यकता है।

आप एक विधि का सुझाव देते समय ओपी में एक गलती करते हैं। एक सूची को क्रमबद्ध करना और फिर इसे समय स्थानांतरित करना , ( एन 2 लॉग एन ) समय नहीं। जब आप दो चीजें करते हैं (जो क्रमशः ( एफ ) और ( जी ) लेते हैं) क्रमिक रूप से तब परिणामी समय जटिलता हे ( एफ + जी ) = ( अधिकतम एफ , जी ) (अधिकांश परिस्थितियों में)।O(nlogn)O(n2logn)O(f)O(g)O(f+g)=O(maxf,g)

समय की जटिलताओं को गुणा करने के लिए, आपको लूप के लिए उपयोग करने की आवश्यकता है। यदि आपके पास लूप की लंबाई है और लूप में प्रत्येक मान के लिए आप एक फ़ंक्शन करते हैं जो O ( g ) लेता है , तो आपको O ( f g ) समय मिलेगा ।fO(g)O(fg)

तो, आपके मामले में आप में सॉर्ट करते हैं और फिर ( एन ) में ट्रांसवर्स करते हैं जिसके परिणामस्वरूप ( एन लॉग एन + एन ) = ( एन लॉग एन ) होता है । यदि छँटाई एल्गोरिथ्म के प्रत्येक तुलना के लिए आपको एक गणना करनी थी जो O ( n ) लेता है , तो यह O ( n 2 log n ) लेगा , लेकिन यहाँ ऐसा नहीं है।O(nlogn)O(n)O(nlogn+n)=O(nlogn)O(n)O(n2logn)


मेरे दावे के बारे में आपकी उत्सुकता के मामले में कि , यह नोट करना महत्वपूर्ण है कि यह हमेशा सच है। लेकिन अगर हे ( जी ) या जी हे ( ) (जो आम कार्यों की एक पूरी मेजबान के लिए रखती है), यह आयोजन करेगा। सबसे आम समय यह नहीं होता है जब अतिरिक्त पैरामीटर शामिल होते हैं और आपको ( 2 सी एन + एन लॉग एन ) जैसे भाव मिलते हैं ।O(f+g)=O(maxf,g)fO(g)gO(f)O(2cn+nlogn)


3

स्टोर के रूप में तत्वों के क्रम का उपयोग करते हुए बूलियन सरणी तकनीक का एक स्पष्ट इन-प्लेस वैरिएंट है (जहां arr[x] == x"पाया गया" तत्व)। विभाजन संस्करण के विपरीत जिसे अधिक सामान्य होने के लिए उचित ठहराया जा सकता है मैं अनिश्चित हूं जब आपको वास्तव में इस तरह की आवश्यकता होगी, लेकिन यह सरल है।

for idx from n-4 to n
    while arr[arr[idx]] != arr[idx]
        swap(arr[arr[idx]], arr[idx])

यह केवल बार-बार arr[idx]उस स्थान पर डालता है arr[idx]जब तक कि आपको वह स्थान पहले से ही न मिल जाए, जिस बिंदु पर यह एक डुप्लिकेट होना चाहिए। ध्यान दें कि प्रत्येक स्वैप की कुल संख्या सही होने के बाद से स्वैप की कुल संख्या से बंधी हुई है ।n


आपको कुछ प्रकार के तर्क देने होंगे कि आंतरिक whileलूप औसत समय में निरंतर चलता है। अन्यथा, यह एक रैखिक-समय एल्गोरिथ्म नहीं है।
डेविड रिचेर्बी

@DavidRicherby यह औसत पर निरंतर समय नहीं चलाता है, लेकिन बाहरी लूप केवल 5 बार चलता है ताकि यह ठीक हो। ध्यान दें कि स्वैप की कुल संख्या से बंधी हुई है क्योंकि प्रत्येक स्वैप अपनी निकास स्थिति को सही बनाता है, इसलिए भले ही डुप्लिकेट मान की संख्या कुल समय अभी भी रैखिक है (उर्फ। यह n d के बजाय n कदम लेता है )। nnnd
विड्राक

उफ़, मैंने किसी तरह ध्यान नहीं दिया कि बाहरी लूप लगातार संख्या में चलता है! (स्वैप की संख्या के बारे में अपने नोट को शामिल करने के लिए संपादित किया गया था और इसलिए भी मैं अपने
डाउनवोट

1

योग से मानों आप घटाएँ i=1ni=(n1)n2

तो, के बाद समय (यह मानते हुए गणित हे (1) है, जो यह वास्तव में नहीं है, लेकिन चलो नाटक) यदि आप एक योग है σ 1 1 और एन के बीच 5 पूर्णांकों:Θ(n)σ1

x1+x2+x3+x4+x5=σ1

माना, यह अच्छा नहीं है, है ना? आप संभवतः यह पता नहीं लगा सकते हैं कि इसे 5 अलग-अलग संख्याओं में कैसे विभाजित किया जाए।

आह, लेकिन यह वह जगह है जहाँ यह मज़ेदार हो जाता है! अब पहले की तरह ही काम करते हैं, लेकिन घटाना वर्गों से मानों का । अब आपके पास है:i=1ni2

x12+x22+x32+x42+x52=σ2

देखें कि मैं इसके साथ कहाँ जा रहा हूँ? शक्तियों 3, 4 और 5 के लिए भी ऐसा ही करें और आपके पास 5 चर में 5 स्वतंत्र समीकरण हैं। मुझे पूरा यकीन है कि आप लिए हल कर सकते हैं ।x

कैविट्स: अंकगणित वास्तव में ओ (1) नहीं है। इसके अलावा, आपको अपने रकम का प्रतिनिधित्व करने के लिए थोड़ी जगह चाहिए; लेकिन के रूप में ज्यादा नहीं के रूप में आप कल्पना कर सकते हैं - आप सबसे सब कुछ modularly, कर सकते हैं, जब तक आप के रूप में ओह, बिट्स; इससे हो जाना चाहिए।log(5n6)


क्या @YuvalFilmus एक ही समाधान का प्रस्ताव नहीं करता है?
fade2black

@ fade2black: ओह, हाँ, यह करता है, क्षमा करें, मैंने उसके समाधान की पहली पंक्ति देखी।
einpoklum

0

समस्या को हल करने का सबसे आसान तरीका है सरणी बनाना जिसमें हम मूल संख्या में प्रत्येक संख्या के लिए संख्याओं की गणना करेंगे, और फिर सभी संख्याओं को से n - 5 तक ले जाएंगे और जाँचेंगे कि क्या संख्या एक से अधिक बार दिखाई देती है, इसके लिए जटिलता स्मृति और समय दोनों में समाधान रैखिक है, या O ( N )1n5O(N)


1
यह वही है @ fade2black का जवाब (हालाँकि आंखों पर थोड़ा आसान है)
LangeHaare

0

किसी सरणी को मैप करें 1 << A[i]और फिर सब कुछ एक साथ XOR करें। आपके डुप्लिकेट वह नंबर होंगे जहां संबंधित बिट बंद है।


पांच डुप्लिकेट हैं, इसलिए कुछ मामलों में एक्सर ट्रिक नहीं टूटेगी।
ईविल

1
इसका चलने का समय । प्रत्येक बिटवेक्टर n बिट्स लंबा होता है, इसलिए आप प्रत्येक बिटवेक्टर ऑपरेशन में O ( n ) समय लेते हैं, और आप ( n 2 ) समय के लिए मूल सरणी के प्रति तत्व एक बिट वेक्टर ऑपरेशन करते हैं । O(n2)nO(n)O(n2)
डीडब्ल्यू

@ DW लेकिन यह देखते हुए कि आमतौर पर हम जिन मशीनों का उपयोग करते हैं, वे 32 या 64-बिट्स में तय की जाती हैं, और ये रन-टाइम (यानी वे स्थिर हैं) में नहीं बदलतीं, उन्हें ऐसा क्यों नहीं माना जाना चाहिए और यह मान लिया जाए कि बिट कार्यों में कर रहे हैं के बजाय हे ( एन ) ? O(1)O(n)
code_dredd

1
@ ऐरे, मुझे लगता है कि आपने अपने प्रश्न का उत्तर दिया। यह देखते हुए कि आमतौर पर हम जिन मशीनों का उपयोग करते हैं, वे 64-बिट्स पर तय की जाती हैं, एक -bit वेक्टर पर एक ऑपरेशन करने का समय O ( n ) है , न कि O ( 1 ) । ऐसा लगता है कि कुछ लेता n / 64 सब पर कुछ आपरेशन करने के लिए निर्देश n एक के टुकड़े n -बिट वेक्टर, और एन / 64 है हे ( एन ) , नहीं हे ( 1 )nO(n)O(1)n/64nnn/64O(n)O(1)
DW

nnO(kn)knk=64O(1)O(k)O(n) instead of O(kn). Are you keeping the k for the sake of completeness/correctness or am I missing something else?
code_dredd

-2
DATA=[1,2,2,2,2,2]

from collections import defaultdict

collated=defaultdict(list):
for item in DATA:
    collated[item].append(item)
    if len(collated) == 5:
        return item.

# n time

4
Welcome to the site. We're a computer science site, so we're looking for algorithms and explanations, not code dumps that require understanding of a particular language and its libraries. In particular, your claim that this code runs in linear time assumes that collated[item].append(item) runs in constant time. Is that really true?
David Richerby

3
Also, you are looking for a value which is repeated five times. In contrast, the OP is looking for five values, which are each repeated twice.
Yuval Filmus
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.