क्या एक एल्गोरिथ्म है जो


21

मैं एक एल्गोरिथ्म के अस्तित्व को साबित या बाधित करना चाहता हूं, जो पूर्णांक की एक सरणी देता है , तीन सूचकांकों i , j और k को खोजता है जैसे कि i < j < k और A [ i ] < A [ j ] < A [ k ] (या पाता है कि रैखिक समय में ऐसा कोई ट्रिपल नहीं है)।Ai,jki<j<kA[i]<A[j]<A[k]

यह एक होमवर्क प्रश्न नहीं है; मैंने इसे एक प्रोग्रामिंग फ़ोरम पर देखा, जिसे "इस तरह के एक एल्गोरिथ्म को लागू करने की कोशिश" के रूप में तैयार किया गया था। मुझे संदेह है कि विभिन्न प्रयोगों के बाद यह असंभव है। मेरा अंतर्ज्ञान मुझे ऐसा बताता है, लेकिन यह वास्तव में किसी भी चीज के लिए गिनती नहीं करता है।

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

[1,5,2,0,3] → (1,2,3)
[5,6,1,2,3] → (1,2,3)
[1,5,2,3] → (1,2,3)
[5,6,1,2,7] → (1,2,7)
[5,6,1,2,7,8] → (1,2,7)
[1,2,999,3] → (1,2,999)
[999,1,2,3] → (1,2,3)
[11,12,8,9,5,6,3,4,1,2,3] → (1,2,3)
[1,5,2,0,-5,-2,-1] → (-5,-2,-1)

मेरा मानना ​​था कि कोई पर ओवररेट कर सकता है , और हर बार एक आई < जे (हमारा वर्तमान जे , वह है), हम एक नया ट्रिपल बनाते हैं और इसे एक सरणी पर धक्का देते हैं। हम प्रत्येक ट्रिपल को पूरा करना और उसकी तुलना करना जारी रखते हैं जब तक कि हमारा एक ट्रिप पूरा नहीं हो जाता। तो यह की तरह है , ! लेकिन मुझे लगता है कि यह मात्र O ( n ) की तुलना में अधिक जटिल है क्योंकि हमारे ट्रिपल ऐरे पर ट्रायल्स की संख्या सबसे खराब स्थिति में इनपुट सूची के आकार के अनुरूप होगी।Ai<jj[1,5,2,0,-5,-2,-1] → 1..2.. -5.. -2.. -1[1,5,2,0,-5,-2,3,-1] → 1..2.. -5.. -2.. 3O(n)


6

ध्यान दें कि सबसे खराब स्थिति (सॉर्ट किए गए सरणी) में भी आपके पास कई उपयुक्त त्रिकोणीय हैं। कृपया उस एल्गोरिथ्म को देने पर विचार करें जिसे आप छद्म कोड के रूप में प्रस्तावित करते हैं; मुझे लगता है कि आपका स्पष्टीकरण पूर्ण नहीं है। Θ(n3)
राफेल

जवाबों:


14

यह सबसे लंबे समय तक वृद्धि की समस्या का रूपांतर है; यह दो सहायक सरणियों और पी का उपयोग करके विकिपीडिया पर प्रस्तुत समाधान है :MP

  • - भंडार की स्थिति कश्मीर छोटा मान की एक [ कश्मीर ] लंबाई का एक वृद्धिमान परिणाम है ऐसी है कि जे में समाप्त एक [ कश्मीर ] सीमा पर कश्मीर मैं (ध्यान दें हमारे पास जे कश्मीर मैं यहाँ, चूँकि j बढ़ती परवर्तीता की लंबाई को दर्शाता है, और k इसकी समाप्ति की स्थिति को दर्शाता है। जाहिर है, हम कभी भी लम्बाई 13 की बढ़ती हुईस्थिति को 11 की स्थिति में समाप्तनहीं कर सकते हैं।M[j]kA[k]jA[k]kijkijk1311 परिभाषा के द्वारा)।ki
  • - दुकानों की पूर्ववर्ती की स्थिति एक [ कश्मीर ] सबसे लंबे समय तक वृद्धिमान परिणाम पर समाप्त करने में एक [ कश्मीर ]P[k]A[k]A[k]

    इसके अलावा एल्गोरिथ्म एक वैरिएबल स्टोर करता है जो अब तक पाए जाने वाले सबसे लंबे समय तक बढ़ने वाली लंबाई का प्रतिनिधित्व करता है।L

यह एल्गोरिथम सबसे खराब स्थिति में चलता है । आपकी समस्या एक विशेष मामला है जो आपको L = 3 पर लौटने की अनुमति देता है जो O ( n ) के रनटाइम को नीचे धकेलता है क्योंकि द्विआधारी खोज केवल दो की लंबाई पर सरणियों पर चलती है, इसलिए यह समय O ( 1 ) के विपरीत है। सामान्य मामले में Θ ( लॉग एन )Θ(nlogn)L=3O(n)O(1)Θ(logn)

संशोधित छद्म कोड पर विचार करें:

 L = 0
 for i = 1, 2, ... n:
    binary search for the largest positive j ≤ L
      such that X[M[j]] < X[i] (or set j = 0 if no such value exists)
    P[i] = M[j]
    if j == L or X[i] < X[M[j+1]]:
       M[j+1] = i
       L = max(L, j+1)
   if L==3 : return true; // you can break here, and return true.
return false; // because L is smaller than 3.

@SaeedAmiri मैंने टिप्पणी देखी, लेकिन मेरे पास इसकी समीक्षा करने का समय नहीं था (मैंने बिस्तर पर जाने से पहले प्रश्न पोस्ट किया था)। मुझे आपके लिंक से संदेह था कि हमारा विशेष मामला L = 3 किसी भी तरह से मदद करेगा, लेकिन विवरण को समझने का मौका नहीं था। मैं इस समय काम पर हूं और समय की कमी है। आश्वस्त रहें कि मैं आपके उत्तर की सराहना करता हूं। मेरे लिए यह धन्यवाद होगा कि इसके भीतर की प्रत्येक पंक्ति को पूरी तरह समझे बिना आपको इसके लिए धन्यवाद देना चाहिए।
क्रिस्टोफर ने

@ सईदअमीर: मैं मानता हूं कि आप यहां अधिक "गैप-फिलिंग" की उम्मीद करते हैं, लेकिन आपको अभी भी कम से कम एक सबूत (हालांकि स्केच) के कोने के तर्क देने होंगे। ओपी के बारे में, वह इटली में स्थित लगता है इसलिए शायद आपकी टिप्पणी और उत्तर के बीच तेजी से सो रहा था (और संभावना है कि वह पूर्वी के साथ व्यस्त है)।
राफेल

@ChristopherDone, मैं आपको परेशान नहीं करना चाहता, क्षमा करें यह मेरी गलती है, आप निश्चित रूप से सही हैं।

+1: यह अच्छी तरह से सामान्य करता है, केवल एक पास बनाता है और स्थान है। O(1)
आर्यभट्ट

ठीक है, अच्छा लग रहा है। सामान्य सबसे लंबे समय तक बढ़ते अनुक्रम एल्गोरिदम के व्यवहार को कम करने में मुझे कुछ समय लगा। उसके बाद, अधिकतम लंबाई == 3 परिवर्तन ठीक है। धन्यवाद!
क्रिस्टोफर

11

कार्यप्रणाली पर एक नोट

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

दो-तत्व संस्करण

आइए छोटे शुरू करें: तीन सूचकांकों की तलाश करें, जिन पर तत्व क्रम में हैं, आइए दो को देखें: ऐसा कि A [ i ] < A [ j ]i<jA[i]<A[j]

तो कम हो रही है (यानी मैं < j , एक [ मैं ] एक [ जे ] , या समतुल्य रूप मैं , एक [ मैं ] एक [ मैं + 1 ] ), तो ऐसी कोई सूचकांकों हैं। अन्यथा, एक इंडेक्स i ऐसा है कि A [ i ] < A [ i + 1 ]Ai<j,A[i]A[j]i,A[i]A[i+1]iA[i]<A[i+1]

यह मामला बहुत सरल है; हम इसे सामान्य करने का प्रयास करेंगे। यह दर्शाता है कि बताई गई समस्या हल नहीं है: अनुरोधित सूचकांक हमेशा मौजूद नहीं होते हैं। इसलिए हम बल्कि कहेंगे कि एल्गोरिथ्म या तो वैध सूचकांक लौटाता है, यदि वे मौजूद हैं, या सही ढंग से दावा करते हैं कि ऐसा कोई सूचकांक मौजूद नहीं है।

एल्गोरिथ्म के साथ आ रहा है

मैं शब्द का उपयोग करेंगे परिणाम को सरणी से एक उद्धरण मतलब करने के लिए सूचकांक से मिलकर कि लगातार नहीं हो सकता है ( ( [ मैं 1 ] , ... , एक [ मैं हूँ ] ) के साथ मैं 1 < < मैं हूँ ), और रन का मतलब लगातार तत्वों के लिए एक ( ( [ मैं ] , एक [ मैं + 1 ] , ... , एक [A(A[i1],,A[im])i1<<imA )।(A[i],A[i+1],,A[i+m1])

हमने सिर्फ यह देखा कि अनुरोधित सूचकांक हमेशा मौजूद नहीं होते हैं। हमारी रणनीति अध्ययन करना होगा जब सूचकांक मौजूद नहीं हैं। हम ऐसा करेंगे मान लीजिए कि हम सूचकांक ढूंढने का प्रयास कर रहे हैं और देख रहे हैं कि हमारी खोज कैसे गलत हो सकती है। फिर ऐसे मामले जहां खोज गलत नहीं होती है, सूचकांकों को खोजने के लिए एक एल्गोरिथ्म प्रदान करेगा।

4,3,2,1,0

दो सूचकांकों के साथ, हम लगातार सूचकांक पा सकते हैं। तीन सूचकांकों के साथ, हम और k = j + 1 के साथ आने में सक्षम नहीं हो सकते हैं । हालांकि, हम उस मामले पर विचार कर सकते हैं जब तीन सख्ती से बढ़ते तत्वों ( [ i ] < [ i [ 1 + 1 ] < [ आई + 2 ] ) को हल किया जाना है, क्योंकि इस तरह के रन को पहचानना आसान है और देखें कि यह शर्त कैसे पूरी नहीं हो सकती है। मान लीजिए कि अनुक्रम में सख्ती से लंबाई 3 की बढ़ती नहीं है।j=i+1k=j+1A[i]<A[i+1]<A[i+2]

4,3,2,1,2,3,2,1,0

अनुक्रम में केवल लंबाई 2 के सख्ती से बढ़ते रन हैं (जिसे मैं शॉर्ट के लिए जोड़े का आदेश दिया जाएगा ), कम से कम लंबाई के कम रन द्वारा अलग किया गया 2. कड़ाई से बढ़ते क्रम में ] एक बढ़ती हुई 3-तत्व अनुक्रम का हिस्सा बनने के लिए, वहाँ एक पहले तत्व होना चाहिए मैं ऐसा है कि एक [ मैं ] < एक [ जे ] या बाद के तत्व कश्मीर ऐसी है कि एक [ j + 1 ] < एक [ कश्मीरA[j]<A[j+1]iA[i]<A[j]kA[j+1]<A[k]

4,3,2,2.5,1.5,0.5,1,0

ik

3,2,1,3.5,2.5,1.5,0.5, -0.5,1.25, -0.25 3,2,1,2.5,1.5,0.5,2,1,0

ijki

2.1,3,2,1,2.5,1.5,0.5,2,1,0 1,2,0,2.5,1.5,0.5

i(i,j)ki(i,j)(i,j)i>jA[i]<A[i]ii(i,j)jA[j]<A[j](i,j)

एल्गोरिथ्म का कथन

पायथन सिंटैक्स में दिया गया है, लेकिन सावधान रहें कि मैंने इसका परीक्षण नहीं किया है।

def subsequence3(A):
    """Return the indices of a subsequence of length 3, or None if there is none."""
    index1 = None; value1 = None
    index2 = None; value2 = None
    for i in range(0,len(A)):
        if index1 == None or A[i] < value1:
            index1 = i; value1 = A[i]
        else if A[i] == value1: pass
        else if index2 == None:
            index2 = (index1, i); value2 = (value1, A[i])
        else if A[i] < value2[1]:
            index2[1] = i; value2[1] = A[i]
        else if A[i] > value2[1]:
            return (index2[0], index2[1], i)
    return None

प्रमाण स्केच

index1सरणी के उस हिस्से के न्यूनतम का सूचकांक है जिसे पहले से ही पता लगाया गया है (यदि यह कई बार होता है, तो हम पहली घटना को बनाए रखते हैं), या Noneपहले तत्व को संसाधित करने से पहले। index2सरणी के पहले से ही निकले हुए हिस्से में लंबाई 2 की बढ़ती हुई संख्या के सूचकांकों को संग्रहीत करता है जिसमें सबसे कम सबसे बड़ा तत्व होता है, या Noneयदि ऐसा क्रम मौजूद नहीं है।

जब return (index2[0], index2[1], i)चलता है, तो हमारे पास value2[0] < value[1](यह एक अपरिवर्तनीय है value2) और value[1] < A[i](संदर्भ से स्पष्ट)। यदि लूप प्रारंभिक रिटर्न को आमंत्रित किए बिना समाप्त होता है, तो या तो value1 == None, जिस स्थिति में लंबाई 2 की कोई बढ़ती हुई संख्या नहीं है, अकेले 3 को छोड़ दें, या value1जिसमें लंबाई 2 की सबसे बड़ी तत्व है , जिसमें बाद की सबसे बड़ी तत्व है। बाद के मामले में, हमारे पास अपरिवर्तनीय रूप से यह है कि लंबाई की बढ़ती संख्या 3 की तुलना में पहले समाप्त नहीं होती है value1; इसलिए इस तरह के किसी भी बाद के अंतिम तत्व, को जोड़ा जाता है value2, जो लंबाई 3 की बढ़ती हुई बाद में बनेगा: क्योंकि हमारे पास भी अपरिवर्तनीय है जो value2लंबाई के बढ़ते 3 का हिस्सा नहीं है, जो पहले से ही बने हुए हिस्से में समाहित हैं, पूरे ऐरे में ऐसा कोई परिणाम नहीं है।

उपर्युक्त आक्रमणकारियों को साबित करना पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।

जटिलता

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

औपचारिक प्रमाण

पाठक को एक अभ्यास के रूप में छोड़ दिया।


8

O(n)O(n)

सबसे पहले, एक स्टैक और एक सहायक सरणी को बनाए रखने के लिए बाएं से दाएं सरणी को पार करें जो आपको प्रत्येक तत्व के लिए बताता है, एक तत्व का सूचकांक इससे अधिक और इसके दाईं ओर।

1

हर बार जब आप सरणी में एक नए तत्व पर विचार करते हैं, यदि वह तत्व स्टैक के शीर्ष तत्व से अधिक है, तो आप इसे स्टैक से पॉप करते हैं, और नए तत्व के इंडेक्स के लिए शीर्ष के अनुरूप ऐक्स सरणी तत्व सेट करते हैं। विचार।

स्टैक से तत्वों को पॉप करना जारी रखें और संबंधित सूचकांक को सेट करें, जबकि वर्तमान तत्व अधिक है। एक बार शीर्ष में एक तत्व होता है जो कम नहीं होता है (या खाली हो जाता है), मौजूदा तत्व को स्टैक पर धकेलें, और उपरोक्त चरण को दोहराते हुए सरणी के अगले तत्व पर आगे बढ़ें।

एक और पास (और एक और ऐक्स सरणी) बनाएं, लेकिन दाएं से बाएं।

1

O(n)

ki

पहले पास के लिए छद्म कोड इस तरह लग सकता है:

Stack <Pair<Elem, Index>> greats;
Elem auxArr[inputArr.Length];

for (Index i = 0; i < inputArr.Length; i++) {

    while (!greats.IsEmpty() && inputArr[i] > greats.PeekTop().Elem) {
        Pair top = greats.Pop();
        auxArr[top.Index] = i;
    }

    Pair p;
    p.Elem = inputArr[i];
    p.Index = i;

    greats.Push(p);
}

"चूंकि आप सरणी के प्रत्येक तत्व को केवल एक स्थिर संख्या मानते हैं, यह O (n) समय है।" ओह, crums। किसी तरह मैंने कई निरंतर पास से इनकार कर दिया था, इसे ओ (एन) के रूप में नहीं छोड़ा। बहुत मूर्ख। मैं आपके स्पष्टीकरण के लिए आभारी हूं, और मैं इसे हल करने के लिए एक बार फिर प्रयास करूंगा।
क्रिस्टोफर ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.