आप निरंतर स्मृति के साथ रैखिक समय में एक स्ट्रिंग में सभी असंतुलित Parens कैसे पा सकते हैं?


11

मुझे एक साक्षात्कार के दौरान निम्नलिखित समस्या दी गई थी:

एक तार देता है जिसमें अन्य अल्फ़ान्यूमेरिक वर्णों के साथ परेंस का कुछ मिश्रण होता है (कोष्ठक या ब्रेसिज़ नहीं - केवल परेंस), उन सभी परनों की पहचान करें जिनमें कोई मेल नहीं है।

उदाहरण के लिए, स्ट्रिंग ") (एब)" में, सूचकांकों में 0 और 5 में ऐसे Parens होते हैं जिनका कोई मिलान नहीं होता है।

मैंने O (n) मेमोरी का उपयोग करते हुए एक कार्यशील O (n) समाधान को आगे रखा, एक स्टैक का उपयोग करके और एक बार स्ट्रेन से पार्न्स को जोड़ने और स्टैक से हटाने के बाद जब भी मुझे एक क्लोजिंग पेरेन का सामना करना पड़ा और स्टैक के शीर्ष समाहित हुआ। एक उद्घाटन पैरा।

बाद में, साक्षात्कारकर्ता ने नोट किया कि समस्या को निरंतर मेमोरी के साथ रैखिक समय में हल किया जा सकता है (जैसा कि इनपुट द्वारा लिया गया है इसके अलावा कोई अतिरिक्त मेमोरी उपयोग नहीं है।)

मैंने पूछा कि कैसे और उसने कहा कि बाईं ओर से एक बार स्ट्रिंग के माध्यम से जाने के बारे में सभी खुले हुए पार्न्स की पहचान करते हैं, और फिर दूसरी बार दाईं ओर से सभी करीबी पार्न की पहचान करते हैं .... या शायद यह दूसरा तरीका था। मुझे वास्तव में समझ नहीं आया और मैं उसे इसके माध्यम से हाथ पकड़ने के लिए नहीं कहना चाहता था।

क्या कोई उसके द्वारा सुझाए गए समाधान को स्पष्ट कर सकता है?


1
हमें आपसे पहले कुछ स्पष्टीकरण की आवश्यकता हो सकती है। क्या "या (") असंतुलित माने जाने वाले "या (") में पहले परिनियन्स हैं? क्या अंतिम परेंस या "()) में अंतिम पैरान्स असंतुलित माने जाते हैं?" या क्या यह कम से कम कार्डिनलिटी के साथ किसी भी पैरेंस के सेट की पहचान करने के लिए पर्याप्त है ताकि उन्हें हटाने से शेष पार्न्स संतुलित हो जाए? या कुछ और? या साक्षात्कार का यह हिस्सा है ताकि एक जवाब किसी भी उचित विनिर्देश को आगे रख सके?
जॉन एल।

मैं कहूंगा कि यह आपके ऊपर निर्भर करता है। शेष संतुलित छोड़ देता है कि किसी भी सेट निकालें।
temporary_user_name

5
फिर उन सभी को हटा दें; पी
वैद्रेक

@Veedrac, निश्चित रूप से (जैसा कि आप जानते हैं) पोस्टर "कोई भी न्यूनतम सेट निकालें ... " में 'न्यूनतम' शब्द भूल गया था ।
एलएसपीस

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

जवाबों:


17

चूंकि यह एक प्रोग्रामिंग पृष्ठभूमि से आता है, न कि एक सैद्धांतिक कंप्यूटर विज्ञान अभ्यास से, मैं मानता हूं कि स्ट्रिंग में एक इंडेक्स को स्टोर करने के लिए O(1) मेमोरी लेता है । सैद्धांतिक कंप्यूटर विज्ञान में, इसका मतलब रैम मॉडल का उपयोग करना होगा; ट्यूरिंग मशीन के साथ यदि आप ऐसा नहीं कर सकता है और आप आवश्यकता होगी Θ(log(n)) स्मृति लंबाई की एक स्ट्रिंग में एक सूचकांक स्टोर करने के लिए n

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

एक स्टैक का उपयोग करना और स्ट्रिंग के माध्यम से एक बार स्ट्रेन के माध्यम से जाना और स्टैक से उन्हें हटाना जब भी मुझे एक समापन पैरा का सामना करना पड़ा और स्टैक के शीर्ष में एक खोलने वाला हिस्सा था

तो इस ढेर में क्या है? यह कभी भी शामिल नहीं होने वाला है ()(एक शुरुआती कोष्ठक के बाद एक कोष्ठक के बाद), जब भी )प्रकट होता है आप (धक्का देने के बजाय पॉप करते हैं )। तो स्टैक हमेशा फॉर्म का होता है )…)(…(- खुलने वाले कोष्ठकों का एक गुच्छा, जिसके बाद कोष्ठक खोलने का एक गुच्छा होता है।

इसका प्रतिनिधित्व करने के लिए आपको स्टैक की आवश्यकता नहीं है। बस बंद कोष्ठक की संख्या और प्रारंभिक कोष्ठक की संख्या याद रखें।

यदि आप इन दो काउंटरों का उपयोग करते हुए, बाएं से दाएं स्ट्रिंग को संसाधित करते हैं, तो आपके पास अंत में क्या बेमेल समापन कोष्ठक की संख्या और बेमेल उद्घाटन कोष्ठक की संख्या है।

Θ(n)

संक्षेप में: स्ट्रिंग को बाएं से दाएं पर संसाधित करें। बेजोड़ उद्घाटन कोष्ठक का एक काउंटर बनाए रखें। यदि आप एक प्रारंभिक कोष्ठक देखते हैं, तो काउंटर बढ़ाएँ। यदि आप एक कोष्ठक को देखते हैं और काउंटर नॉनजेरो है, तो काउंटर को घटाएं। यदि आपको एक बंद कोष्ठक दिखाई देता है और काउंटर शून्य है, तो वर्तमान सूचकांक को बेमेल समापन कोष्ठक के रूप में आउटपुट करता है।

काउंटर का अंतिम मूल्य बेमेल उद्घाटन कोष्ठक की संख्या है, लेकिन यह आपको उनकी स्थिति नहीं देता है। ध्यान दें कि समस्या सममित है। बेमेल उद्घाटन कोष्ठक के पदों को सूचीबद्ध करने के लिए, बस एल्गोरिथ्म को विपरीत दिशा में चलाएं।

व्यायाम 1: इसे औपचारिक संकेतन (गणित, स्यूडोकोड या अपनी पसंदीदा प्रोग्रामिंग भाषा) में लिखें।

व्यायाम 2: अपने आप को समझाएं कि यह Apass.Jack के समान ही एल्गोरिदम है , बस अलग तरीके से समझाया गया है।


ओह, बहुत अच्छा गिल्स, बहुत अच्छी तरह से समझाया। मैं अब पूरी तरह से समझ गया हूं। मुझे आपके एक सवाल पर जवाब मिलने में काफी साल हो गए हैं।
temporary_user_name

"यदि आप अंत में बेमेल कोष्ठक के पदों की रिपोर्ट करना चाहते हैं, तो आपको प्रत्येक कोष्ठक की स्थिति को याद रखना होगा।" काफी नहीं। रैखिक समय का मतलब सिंगल पास नहीं है। आप बेमेल पक्ष में किसी भी कोष्ठक को खोजने और उन्हें चिह्नित करने के लिए एक दूसरा पास कर सकते हैं।
मूंग बतख

अंतिम चरण के लिए, आपको इसे रिवर्स में चलाने की ज़रूरत नहीं है, आप बस अंतिम N को चिह्नित कर सकते हैं "(" बेमेल के रूप में।
मूइंग डक

1
@MingDuck यह काम नहीं करता है। जैसे (()
orlp

जबकि मुझे वास्तव में यह जवाब पसंद है, कुछ मुझे इसके बारे में परेशान करता है। यह कुछ ऐसा है "मुझे किसी तरह से स्थिति को याद रखने की आवश्यकता है और मुझे लगता है कि मेरे पास जो मुद्दा है वह यह है: आप मेमोरी का उपभोग किए बिना" या "वर्तमान सूचकांक का उत्पादन कैसे करते हैं (या एक विशिष्ट संदर्भ जहां आपके आउटपुट इस तरह से उपभोग किए जाते हैं) आपके आउटपुट का ऑर्डर w- कोई फर्क नहीं पड़ता)
-douard

8

चूंकि हम केवल सभी अल्फ़ान्यूमेरिक वर्णों को अनदेखा कर सकते हैं, हम मान लेंगे कि स्ट्रिंग में अभी से केवल कोष्ठक शामिल हैं। सवाल के रूप में, एक प्रकार का कोष्ठक है, "()"।

यदि हम संतुलित कोष्ठकों को हटाते रहें, जब तक कि अधिक संतुलित कोष्ठक नहीं हटाए जा सकते, तब तक शेष सभी कोष्ठक "") ...) ... (... (", जो सभी असंतुलित कोष्ठक हैं, जैसा दिखना चाहिए। यह अवलोकन बताता है कि हमें उस मोड़ को खोजना चाहिए।" , जिसके पहले हमारे पास असंतुलित समापन कोष्ठक हैं और उसके बाद हमारे पास असंतुलित उद्घाटन कोष्ठक हैं।

यहाँ एल्गोरिथ्म है। संक्षेप में, यह पहले मोड़ की गणना करता है। फिर यह अतिरिक्त समापन कोष्ठक का उत्पादन करता है, स्ट्रिंग को प्रारंभ से दाईं ओर मोड़ता है। सममित रूप से, यह अतिरिक्त उद्घाटन कोष्ठक का उत्पादन करता है, अंत से बाईं ओर मोड़ बिंदु तक।


strn

आरंभ में turning_point=0, maximum_count=0, count=0। निम्नलिखित में iसे प्रत्येक के 0लिए n-1

  1. यदि str[i] = ')', 1 से जोड़ें count; अन्यथा, घटाना 1।
  2. यदि count > maximum_count, सेट turning_point=iऔर maximum_count=count

अब turning_pointमोड़ का सूचकांक है।

रीसेट करें maximum_count=0, count=0। निम्नलिखित में iसे प्रत्येक के 0लिए turning_point

  1. यदि str[i] = ')', 1 से जोड़ें count; अन्यथा, घटाना 1।
  2. यदि count > maximum_count, सेट करें maximum_count = countiअसंतुलित समापन कोष्ठक के सूचकांक के रूप में आउटपुट ।

रीसेट करें maximum_count=0, count=0। प्रत्येक के लिए iसे n-1करने के लिए turning_point+1नीचे की ओर निम्नलिखित है।

  1. यदि str[j] = '(', 1 से जोड़ें count; अन्यथा, घटाना 1।
  2. यदि count > maximum_count, सेट करें maximum_count = countiएक असंतुलित उद्घाटन कोष्ठक के सूचकांक के रूप में आउटपुट ।

O(n)O(1)O(u)u


यदि हमने ऊपर एल्गोरिथ्म का विश्लेषण किया है, तो हम देखेंगे कि वास्तव में, हमें मोड़ को खोजने और उपयोग करने की आवश्यकता नहीं है। सभी असंतुलित खुलने वाले कोष्ठकों से पहले सभी असंतुलित समापन कोष्ठकों को देखने के बाद अच्छा अवलोकन किया जा सकता है, हालांकि इसे दिलचस्प नहीं माना जा सकता है।

यहाँ पायथन में कोड है

कई परीक्षा परिणाम देखने के लिए बस "रन" मारो।


व्यायाम 1. दिखाएँ कि उपरोक्त एल्गोरिथम कम से कम कार्डिनैलिटी के साथ कोष्ठक के एक सेट का उत्पादन करेगा, ताकि शेष कोष्ठक संतुलित हो।

समस्या 1. क्या हम एल्गोरिथ्म को उस स्थिति में सामान्य कर सकते हैं जब स्ट्रिंग में दो प्रकार के कोष्ठक होते हैं जैसे "() []"? हमें यह निर्धारित करना होगा कि नई स्थिति को कैसे पहचानें और उसका इलाज करें, इंटरलेविंग केस, "([)]"।


योग्य, व्यायाम 1 और समस्या 1, प्यारा। आपके द्वारा वर्णित एल्गोरिदम का तर्क आश्चर्यजनक रूप से कठिन है। मुझे इसे प्राप्त करने के लिए कल इसे कोड करना होगा।
temporary_user_name

ऐसा लगता है कि मैं बल्कि स्पष्ट लेकिन सबसे महत्वपूर्ण स्पष्टीकरण याद किया। तर्क, वास्तव में, बहुत सरल है। सबसे पहले, हम प्रत्येक अतिरिक्त ओपनिंग कोष्ठक का उत्पादन करते हैं। एक बार जब हम मोड़ को पार कर लेते हैं, तो हम प्रत्येक अतिरिक्त समापन कोष्ठक का उत्पादन करते हैं। किया हुआ।
जॉन एल।

असंतुलित ओपनिंग कोष्ठकों को खोजना गलत है। Ie यदि आपकी गिरफ्तारी "())" है, p 2 है और p + 1 गिरफ्तारी सीमा के बाहर है। बस एक विचार - असंतुलित खुलने वाले कोष्ठकों को खोजने के लिए आप असंतुलित समापन कोष्ठक (निश्चित रूप से उलट अनुकूलित अनुक्रमित के साथ) को खोजने के लिए एल्गोरिथ्म का उपयोग कर सकते हैं।
OzrenTkalcecKrznaric

p+1

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