एक तत्व जो दो सरणियों में भिन्न होता है। इसे कुशलता से कैसे पाया जाए?


22

मैं एक कोडिंग साक्षात्कार की तैयारी कर रहा हूं और मैं वास्तव में इस समस्या को हल करने के लिए सबसे कुशल तरीका नहीं खोज सकता।

मान लें कि हमारे पास दो एरे हैं, जो कि अनसोल्ड हैं। Array 2 में एक संख्या होती है जो Array 1 नहीं करता है। दोनों सरणियों में यादृच्छिक रूप से स्थित संख्याएं हैं, जरूरी नहीं कि एक ही क्रम में या एक ही सूचक पर। उदाहरण के लिए:

ऐरे 1 [78,11, 143, 84, 77, 1, 26, 35 .... एन]

ऐरे 2 [11,84, 35, 25, 77, 78, 26, 143 ... 21 ... एन + 1]

जो संख्या भिन्न होती है, उसे खोजने के लिए सबसे तेज़ एल्गोरिथम क्या है? इसका रनिंग टाइम क्या है? इस उदाहरण में, हम जिस संख्या की तलाश कर रहे हैं, वह 21 है।

मेरा विचार एरे 1 के माध्यम से चलाने और सरणी 2 से उस मान को हटाने का था। समाप्त होने तक Iterate करें। यह चलने के समय, सही के आसपास होना चाहिए ?O(nlogn)


@Jandvorak आप लोगों को प्रतिक्रियाओं के लिए धन्यवाद। मैं देर से उठा था और यह पोस्ट करने के बाद सो गया। सरणी अनसर्टेड है, और सभी आइटम दोनों सरणियों में यादृच्छिक सूचकांक में दिखाई देते हैं।
कोन्स्टेंटिनो स्पार्किस

@KonstantinoSparakis: यह स्पष्टीकरण उन उत्तरों को अमान्य करता है जो मानते हैं कि दोनों सरणियों में एक ही स्थिति में तत्व शामिल हैं।
मारियो सेरवेरा


@Paparazzi बस एक समाधान की तलाश में था जो मैं मेटा सॉफ्टवेयर इंजीनियरिंग में पढ़ा था, जहां एक समाधान प्राप्त करने के लिए जाना था, लेकिन उस समय मुझे सीएस फोरम के बारे में पता नहीं था। मैंने इसे साफ करने के लिए मॉड को अधिसूचित किया है।
कोन्स्टेंटिनो स्पार्किस

@ Paparazzi वहाँ एक मेटा पोस्ट है कि समर्थन कर रहा है? मैं व्यक्तिगत रूप से उस नीति को अच्छी तरह से लागू करने का कोई तरीका नहीं देखता हूं।
djechlin

जवाबों:


30

मैं इस समस्या को हल करने के चार मुख्य तरीके देखता हूं, अलग-अलग समय के साथ:

  • समाधान: यह वह समाधान होगा जो आप प्रस्तावित करते हैं। ध्यान दें कि, चूंकि सरणियाँ अनसोल्ड हैं, इसलिए विलोपन में रैखिक समय लगता है। आप n विलोपन करते हैं; इसलिए, यह एल्गोरिथ्म द्विघात समय लेता है।O(n2)n

  • समाधान: पहले से सरणियों को क्रमबद्ध करें; फिर, विशिष्ट तत्व की पहचान करने के लिए एक रेखीय खोज करें। इस समाधान में, चल रहे समय को सॉर्टिंग ऑपरेशन द्वारा हावी किया जाता है, इसलिए( एन)O(nlogn) ऊपरी बाध्य।O(nlogn)

जब आप किसी समस्या के समाधान की पहचान करते हैं, तो आपको हमेशा खुद से पूछना चाहिए: क्या मैं बेहतर कर सकता हूं? इस मामले में, आप डेटा संरचनाओं का एक चतुर उपयोग कर सकते हैं। ध्यान दें कि आपको केवल एक सरणी को पुनरावृत्त करना है और दूसरे सरणी में बार-बार लुकअप करना है। क्या डेटा संरचना आपको निरंतर समय में (अपेक्षित) में लुकअप करने की अनुमति देती है? आपने सही अनुमान लगाया: एक हैश तालिका

  • समाधान (अपेक्षित): पहले सरणी को पुनरावृत्त करें और एक हैश तालिका में तत्वों को संग्रहीत करें; फिर, दूसरी सारणी में एक रेखीय स्कैन करें, हैश तालिका में प्रत्येक तत्व को देखें। उस तत्व को लौटाएं जो हैश तालिका में नहीं मिला है। यह लीनियर-टाइम सॉल्यूशन किसी भी प्रकार के तत्व के लिए काम करता है जिसे आप हैश फंक्शन में पास कर सकते हैं (उदाहरण के लिए, यह स्ट्रिंग्स के सरणियों के लिए समान रूप से काम करेगा)।O(n)

यदि आप ऊपरी-सीमा की गारंटी चाहते हैं और सरणियों को पूर्णांक से बना है, तो सबसे अच्छा समाधान है, शायद, टोबी अलाफिन द्वारा सुझाया गया (भले ही यह समाधान आपको दूसरे सरणी में भिन्न तत्व के सूचकांक नहीं देगा) :

  • समाधान (गारंटी): पहले सरणी के तत्वों को योग करें। फिर, दूसरे सरणी के तत्वों को योग करें। अंत में, घटाव प्रदर्शन करते हैं। ध्यान दें कि इस समाधान को वास्तव में किसी भी डेटा प्रकार के लिए सामान्यीकृत किया जा सकता है, जिसके मूल्यों को निश्चित लंबाई वाले बिट स्ट्रिंग्स के रूप में दर्शाया जा सकता है, जोबिटवाइज़ एक्सओआर ऑपरेटर केलिए धन्यवाद है। इल्मरी करोनन केउत्तरमें यह अच्छी तरह से समझाया गया है। हे(n)

अंत में, एक और संभावना (पूर्णांक सरणियों की एक ही धारणा के तहत) एक रेखीय-समय छँटाई algortihm का उपयोग करने के लिए होगी जैसे कि गिनती की तरह। यह O ( n) से सॉर्टिंग-आधारित समाधान के चल रहे समय को कम करेगा से O ( n )हे(nएलजीn)हे(n)


4
यदि संख्या काफी बड़ी है, तो योग रैखिक नहीं है, हालांकि।
सर्ज बोर्श

9
योग एल्गोरिथ्म के बारे में एक अच्छी बात यह है कि यह किसी भी एबेलियन समूह के साथ काम करता है, न कि केवल पूर्णांक के साथ (सबसे विशेष रूप से uint64; cc @sarge)।
जॉन ड्वोरक

6
@ अब्दुल की बात यह है कि यदि आपके पूर्णांक बहुत बड़े हैं, तो आप इसे जोड़ने के लिए का नाटक नहीं कर सकते । मेरा मानना ​​है कि यदि आप उस के लिए खाते हैं तो जटिलता ( एन एल एन एन ) तक बढ़ती है। सामान्य अतिरिक्त के बजाय XOR का उपयोग करना, हालांकि, इनपुट में मनमाने ढंग से बड़ी संख्या के लिए अनुमति देते समय, हालांकि। हे(n)हे(nlnn)
जॉन ड्वोरक

2
@JDDvorak नहीं, यह नहीं है। आप मान रहे हैं कि एबेलियन समूह पर परिभाषित ऑपरेशन में लगातार समय लगता है। यह अभी नहीं माना जा सकता है।
UTF-8

2
@ UTF-8 मैं ऐसा नहीं मान रहा हूं। लेकिन यह परिमित समूहों (uint64) में ऐसा करता है, और इन-डिजिट-वार जोड़ ( अलावा ) आउट-ऑफ-प्लेस ऑपरेंड के आकार में रैखिक है। तो, इस तरह के समूहों में राशि की गणना है ऑपरेंड का कुल आकार में रैखिक समय। जेडn
जॉन ड्वोरक

16

अंतर-ऑफ-द रकम समाधान द्वारा प्रस्तावित टोबी और मारियो वास्तव में जिसके लिए हम एक (निरंतर समय) द्विआधारी आपरेशन परिभाषित कर सकते हैं किसी भी अन्य डेटा प्रकार के लिए सामान्यीकृत किया जा सकता है कि:Θ(n)

  • कुल में, इस तरह है कि किसी भी मूल्यों के लिए और , एक परिभाषित किया गया है एक ही प्रकार के (या इसके बारे में कुछ उचित महाप्रकार, जिसके लिए ऑपरेटर के कम से कम अभी भी परिभाषित किया गया है);
  • साहचर्य , ऐसी है कि ;(सी)=()सी
  • विनिमेय , ऐसी है कि ; तथा=
  • cancellative एक व्युत्क्रम ऑपरेटर वहां मौजूद हैं, जैसे कि कि संतुष्ट करता है ( एक ) = एक । तकनीकी तौर पर, यह उलटा आपरेशन भी जरूरी निरंतर समय हो सकता है, के रूप में "घटाकर" दो की रकम नहीं है जब तक n तत्व एक से अधिक नहीं ले करता है हे ( एन ) समय।()=nहे(n)

(यदि प्रकार केवल विशिष्ट मानों की एक सीमित संख्या ले सकता है, तो ये गुण इसे एबिलियन समूह में बनाने के लिए पर्याप्त हैं ; भले ही ऐसा न हो, यह कम से कम एक कमिटेटिव कैंसिलेटिव सेग्मेंट होगा ।)

इस तरह के एक आपरेशन का उपयोग करते हुए , हम एक सरणी के "राशि" को परिभाषित कर सकते एक = ( एक 1 , एक 2 , ... , एक एन ) के रूप में ( =(1,2,...,n) यह देखते हुए एक और सरणी= ( 1 , बी 2 , ... , n , n + 1 ) सभी तत्वों वाली एक के अलावा एक अतिरिक्त तत्व एक्स , हम इस प्रकार है (

()=12n
=(1,2,...,n,n+1)एक्स , और इसलिए हम कंप्यूटिंग द्वारा इस अतिरिक्त तत्व पा सकते हैं: एक्स = ( ()=()एक्स
एक्स=()()

उदाहरण के लिए, यदि सरणियों में मानों पूर्णांक हैं, तो इसके लिए (या पूर्णांक मॉड्यूलर अलावा परिमित-लंबाई पूर्णांकों प्रकार के लिए) ऑपरेटर के रूप में इस्तेमाल किया जा सकता , उलटा आपरेशन के रूप में घटाव के साथ । वैकल्पिक रूप से, के लिए किसी भी डेटा प्रकार जिनके मान निर्धारित लंबाई बिट श्रृंखला के रूप में प्रतिनिधित्व किया जा सकता है, हम उपयोग कर सकते हैं XOR बिटवाइज़ दोनों के रूप में और

आम तौर पर, हम बिटवेअर XOR विधि को चर लंबाई के तारों पर भी लागू कर सकते हैं, उन्हें आवश्यक रूप से एक ही लंबाई तक पैडिंग करके, जब तक कि हमारे पास अंत में गद्दी को उलटने के लिए कोई रास्ता नहीं है।

कुछ मामलों में, यह तुच्छ है। उदाहरण के लिए, C- शैली के शून्य समाप्त बाइट स्ट्रिंग्स को स्पष्ट रूप से अपनी स्वयं की लंबाई एन्कोड किया जाता है, इसलिए उनके लिए यह विधि लागू करना तुच्छ है: जब XORing दो स्ट्रिंग्स, छोटे को अपनी बाइट मैच के लिए null बाइट्स के साथ पैड देता है, और किसी भी अतिरिक्त ट्रेलिंग नल को ट्रिम करता है अंतिम परिणाम। ध्यान दें कि मध्यवर्ती XOR- राशि स्ट्रिंग्स में नल बाइट्स हो सकते हैं, हालांकि, आपको उनकी लंबाई स्पष्ट रूप से संग्रहीत करने की आवश्यकता होगी (लेकिन आपको केवल उनमें से एक या दो की आवश्यकता होगी)।

अधिक आम तौर पर, एक विधि जो मनमाने ढंग से बिट स्ट्रिंग्स के लिए काम करेगी, वह एक-बिट पैडिंग को लागू करने के लिए होगी , जहां प्रत्येक इनपुट बिटस्ट्रिंग को बिट के साथ गद्देदार किया जाता है और फिर (गद्देदार) की लंबाई से मिलान करने के लिए आवश्यक 0 बिट्स के साथ सबसे लंबा इनपुट स्ट्रिंग। (बेशक, इस पैडिंग को पहले से स्पष्ट रूप से किए जाने की आवश्यकता नहीं है; हम XOR राशि की गणना करते समय आवश्यकतानुसार इसे लागू कर सकते हैं।) अंत में, हमें बस किसी भी अनुगामी 0 बिट्स और अंतिम 1 बिट से पट्टी करने की आवश्यकता है । परिणाम। वैकल्पिक रूप से, यदि हम जानते थे कि तार अधिकतम 2 32 पर थे1001232बाइट्स लंबे समय तक, हम प्रत्येक स्ट्रिंग की लंबाई को 32-बिट पूर्णांक के रूप में एन्कोड कर सकते हैं और इसे स्ट्रिंग पर प्रीपेन्ड कर सकते हैं। या हम कुछ उपसर्ग कोड का उपयोग करके मनमानी स्ट्रिंग लंबाई भी सांकेतिक शब्दों में बदलना कर सकते हैं , और उन स्ट्रिंग्स को प्रस्तुत कर सकते हैं। अन्य संभावित एनकोडिंग भी मौजूद हैं।

वास्तव में, चूंकि कंप्यूटर पर किसी भी प्रकार के डेटा को दर्शाया जा सकता है, परिभाषा के अनुसार, एक परिमित-लंबाई बिट स्ट्रिंग के रूप में दर्शाया जाता है, इस पद्धति से समस्या का एक सामान्य समाधान निकलता है।Θ(n)

एकमात्र संभावित मुश्किल हिस्सा यह है कि, काम को रद्द करने के लिए, हमें प्रत्येक मूल्य के लिए एक अद्वितीय विहित बिटस्ट्रिंग प्रतिनिधित्व चुनने की आवश्यकता है, जो मुश्किल हो सकता है (वास्तव में, संभवत: कम्प्यूटेशनल रूप से अनुचित भी) यदि दो सरणियों में इनपुट मान दिए जा सकते हैं। विभिन्न समकक्ष अभ्यावेदन में। हालाँकि, यह इस पद्धति की एक विशिष्ट कमजोरी नहीं है; इस समस्या को हल करने के किसी अन्य तरीके को भी विफल किया जा सकता है यदि इनपुट में उन मानों को शामिल करने की अनुमति है जिनकी तुल्यता अपरिहार्य है।


वाह इस पर बहुत दिलचस्प लग रहा है। धन्यवाद @IlmariKaronen
कोन्स्टेंटिनो स्पार्किस

14

मैं इसे टोबी के उत्तर पर एक टिप्पणी के रूप में पोस्ट करूंगा, लेकिन मेरे पास अभी तक प्रतिष्ठा नहीं है।

प्रत्येक सूची के योग की गणना के विकल्प के रूप में (विशेष रूप से यदि वे बड़ी सूची में हैं या बहुत बड़ी संख्या में हैं जो आपके डेटा प्रकार को अतिप्रवाह कर सकते हैं) जब आप इसके बजाय xor का उपयोग कर सकते हैं।

बस प्रत्येक सूची के xor-sum (यानी x [0] ^ x [1] ^ x [2] ... x [n]) की गणना करें और फिर उन दो मानों को xor करें। यह आपको बाहरी वस्तु (लेकिन सूचकांक नहीं) का मूल्य देगा।

यह अभी भी O (n) है और अतिप्रवाह के साथ किसी भी मुद्दे से बचा जाता है।


3
मैं भी XOR का उपयोग करता हूं, क्योंकि यह थोड़ा सा लगता है, लेकिन उचित होने के लिए, अतिप्रवाह वास्तव में एक मुद्दा नहीं है जब तक कि आप जिस भाषा में इसे लागू कर रहे हैं वह लपेटकर ओवरफ्लो का समर्थन करता है।
मार्टिन एंडर

14

तत्व = सम (ऐरे २) - सम (ऐरे १)

मुझे पूरी तरह से संदेह है कि यह सबसे इष्टतम एल्गोरिथ्म है। लेकिन यह समस्या को हल करने का एक और तरीका है, और इसे हल करने का सबसे सरल तरीका है। आशा करता हूँ की ये काम करेगा।

यदि जोड़े गए तत्वों की संख्या एक से अधिक है, तो यह काम नहीं करेगा।

मेरे जवाब में सबसे अच्छा, सबसे खराब और औसत मामले के लिए एक ही रन टाइम जटिलता है,

EDIT
कुछ सोच के बाद, मुझे लगता है कि मेरा जवाब आपका समाधान है।

nn-11=n-12=n+1-1=n

2n-12-1=1

2n-1+1=2n

Θ(n)

EDIT:
डेटा प्रकार के साथ कुछ समस्याओं के कारण, जैसा कि reffu द्वारा सुझाया गया XOR योग अधिक उपयुक्त होगा।


ध्यान दें कि यदि आपके मान फ़्लोट हैं, तो यह विधि एक सटीक उत्तर नहीं दे सकती है, क्योंकि संख्याओं के योग में राउंडऑफ़ त्रुटियां हो सकती हैं। यह पूर्णांक मानों के लिए काम करेगा, हालांकि, बशर्ते कि आपके a) आपके पूर्णांक प्रकार ने ओवरफ्लो पर रैप-अराउंड व्यवहार को अच्छी तरह से परिभाषित किया हो, या b) आप सॉम्स को एक विस्तृत प्रकार के चर में संग्रहीत करते हैं जो कि वे अतिप्रवाह नहीं कर सकते हैं।
इल्मरी करोनें

रूबी की "बिगएनम" क्लास संभवतः इसे संभाल सकती है।
तोबी अलाफिन

यह बिल्कुल काम नहीं करता है यदि आपके सरणी में उदाहरण के तार शामिल हैं, या बस किसी भी चीज़ के बारे में जो सार्थक रूप से नहीं जोड़ा जा सकता है।
gnasher729

हाँ, मुझे एहसास हुआ। 'XOR' का उपयोग करने के बारे में क्या? क्या यह तैरने के लिए काम करेगा?
तोबी अलाफिन

हां और भी संकेत और सामान्य रूप से कुछ भी जिसमें निश्चित संख्या बिट्स होते हैं। कई भाषाएं इसका समर्थन नहीं करती हैं, लेकिन यह एक मौलिक समस्या नहीं है। मॉड्यूलर जोड़ / घटाव एक ही मामलों में काम करेगा।
हेरोल्ड

1

मान लें कि सरणी 2 को सरणी 1 बनाकर और यादृच्छिक स्थिति में एक तत्व सम्मिलित करके बनाया गया था, या सरणी 1 को सरणी 2 लेकर और यादृच्छिक तत्व को हटाकर बनाया गया था।

यदि सभी सरणी तत्व अलग होने की गारंटी दी जाती है, तो समय O (ln n) है। आप स्थान n / 2 पर तत्वों की तुलना करते हैं। यदि वे समान हैं, तो अतिरिक्त तत्व n / 2 + 1 से सरणी के अंत तक है, अन्यथा यह 0 से n / 2 तक है। और इसी तरह।

यदि सरणी तत्वों को अलग होने की गारंटी नहीं है: आप सरणी 1 में n नंबर 1, और संख्या 2 कहीं भी डाल सकते हैं। 2. उस स्थिति में आप यह नहीं जान सकते कि नंबर 2 बिना देखे कहां है? सरणी तत्व। इसलिए O (n)।

पुनश्च। चूंकि आवश्यकताएँ बदल गईं, जो उपलब्ध है उसके लिए अपने पुस्तकालय की जाँच करें। MacOS / iOS पर, आप एक NSCountedSet बनाते हैं, सरणी 2 से सभी संख्याएँ जोड़ते हैं, सरणी 1 से सभी संख्याएँ निकालते हैं, और जो बचा है वह सब कुछ है जो कि सरणी 2 में है, लेकिन सरणी 1 में नहीं है, इस दावे पर भरोसा किए बिना कि एक अतिरिक्त है आइटम।


यह उत्तर हाजिर था, लेकिन प्रश्न को एक नई आवश्यकता के साथ संपादित किया गया है जो आपकी धारणा को अमान्य करता है।
मारियो सेरवेरा

आपका नया जवाब सही लगता है। समय जटिलता क्या है।
तोबी अलाफिन

ठीक है, पहले कोड लिखने के लिए आवश्यक समय क्या है। यह तुच्छ है। NSCountedSet हैशिंग का उपयोग करता है, इसलिए समय की जटिलता "आमतौर पर रैखिक" होती है।
gnasher729

-1

var सबसे छोटा, सबसे लंबा;

त्वरित संदर्भ के लिए एक नक्शे में सबसे छोटा और सबसे लंबे समय तक लूप को तब तक परिवर्तित करें जब तक कि वर्तमान मूल्य मानचित्र में न हो।

जावास्क्रिप्ट में कुछ इस तरह:

if (arr1.length> arr2.length) {सबसे छोटा = arr2; सबसे लंबा = बन्दी; } और {सबसे छोटा = arr1; सबसे लंबा = गिरफ्तारी 2; }

var map = shortest.reduce (फ़ंक्शन (obj, value) {obj [value] = true; रिटर्न obj;}, {});

var अंतर = longest.find (फ़ंक्शन (मान) {वापसी !!! नक्शा [मूल्य];});


स्पष्टीकरण के बिना कोड यहां एक अच्छे उत्तर के रूप में नहीं गिना जाता है। इसके अलावा आप क्यों इस्तेमाल करेंगे !!! ?
ईविल

-1

अंतरिक्ष जटिलता के संदर्भ में O (N) समय जटिलता में समाधान O (1)

समस्या कथन: मान लें कि array2 में array1 के सभी तत्व हैं और array1 में मौजूद अन्य तत्व नहीं हैं।

समाधान यह है: हम एक्स 1 का उपयोग उस तत्व को खोजने के लिए करते हैं जो सरणी 1 में मौजूद नहीं है, इसलिए चरण 1 हैं। सरणी 1 से शुरू करें और सभी तत्वों के एक्सआर करें और उन्हें एक चर में संग्रहीत करें। 2. array2 लें और चर के साथ सभी तत्वों के xor करें जो array1 के xor को स्टोर करते हैं। 3. ऑपरेशन करने के बाद हमारे चर में वह तत्व होगा जो केवल array2 में मौजूद है। उपरोक्त एल्गोरिथ्म xor की निम्न संपत्ति के कारण काम करता है "a xor a = 0" "a xor 0 = a" मुझे आशा है कि यह आपकी समस्या को हल करता है। साथ ही उपरोक्त सुझाए गए उपाय भी ठीक हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.