नीचे दिया गया उत्तर 'धोखा' है, जबकि इसमें ऑपरेशंस के बीच किसी भी स्थान का उपयोग नहीं किया जाता है, ऑपरेशन स्वयं से अधिक स्पेस का उपयोग कर सकते हैं । इस थ्रेड में कहीं और उत्तर देखें, जिसमें यह समस्या न हो।O(1)
जबकि मेरे पास आपके सटीक प्रश्न का उत्तर नहीं है, मुझे एक एल्गोरिथ्म मिला जो बजाय समय में काम करता है । मेरा मानना है कि यह तंग है, हालांकि मेरे पास कोई सबूत नहीं है। यदि कुछ भी हो, तो एल्गोरिथ्म से पता चलता है कि की निचली सीमा को साबित करने की कोशिश निरर्थक है, इसलिए यह आपके प्रश्न का उत्तर देने में मदद कर सकता है।O(n)O(n)O(n−−√)O(n)O(n)
मैं दो एल्गोरिदम प्रस्तुत करता हूं, पहला पॉप के लिए चलने का समय और दूसरा पॉप के लिए चलने वाले समय के साथ एक सरल एल्गोरिथम है । मैं मुख्य रूप से इसकी सादगी के कारण पहले एक का वर्णन करता हूं ताकि दूसरे को समझना आसान हो।ओ ( √O(n)O(n−−√)
अधिक विवरण देने के लिए: पहला कोई अतिरिक्त स्थान का उपयोग नहीं करता है, सबसे खराब स्थिति (और परिशोधन) पुश और एक सबसे खराब स्थिति (और परिशोधन) पॉप है, लेकिन सबसे खराब स्थिति व्यवहार हमेशा ट्रिगर नहीं होता है। चूंकि यह दो कतारों से परे किसी अतिरिक्त स्थान का उपयोग नहीं करता है, यह रॉस स्नाइडर द्वारा प्रस्तुत समाधान की तुलना में थोड़ा 'बेहतर' है।O ( n )O(1)O(n)
दूसरा एकल पूर्णांक फ़ील्ड का उपयोग करता है (इसलिए अतिरिक्त स्थान), सबसे खराब स्थिति (और परिशोधित) पुश और amortized पॉप है। यह समय चल रहा है इसलिए 'सरल' दृष्टिकोण की तुलना में काफी बेहतर है, फिर भी यह कुछ अतिरिक्त स्थान का उपयोग करता है।हे ( 1 ) हे ( √O(1)O(1)O(n−−√)
पहला एल्गोरिथ्म
हमारी दो कतारें हैं: कतार और कतार । हमारी 'पुश कतार' होगी , जबकि 'स्टैक ऑर्डर' में पहले से मौजूद कतार होगी।एस ई सी ओ एन डी एफ मैं r रों टी एस ई सी ओ एन डीfirstsecondfirstsecond
- पुश को पैरामीटर को सरल रूप से लागू करके किया जाता है ।first
- पोपिंग निम्नानुसार किया जाता है। यदि खाली है, तो हम बस धोखा देते हैं और परिणाम वापस करते हैं। अन्यथा, हम रिवर्स , के सभी संलग्न को और स्वैप और । हम तब धोखा देते हैं और dequeue के परिणाम को वापस करते हैं।एस ई सी ओ एन डी एफ मैं r रों टी एस ई सी ओ एन डी एफ मैं r रों टी च मैं r रों टी एस ई सी ओ एन डी एस ई सी ओ एन डीfirstsecondfirstsecondfirstfirstsecondsecond
पहली एल्गोरिथ्म के लिए सी # कोड
यह काफी पठनीय होना चाहिए, भले ही आपने पहले कभी C # नहीं देखा हो। यदि आप नहीं जानते हैं कि जेनेरिक क्या हैं, तो स्ट्रिंग्स के ढेर के लिए, अपने दिमाग में 'टी' के सभी उदाहरणों को बदलें।
public class Stack<T> {
private Queue<T> first = new Queue<T>();
private Queue<T> second = new Queue<T>();
public void Push(T value) {
first.Enqueue(value);
}
public T Pop() {
if (first.Count == 0) {
if (second.Count > 0)
return second.Dequeue();
else
throw new InvalidOperationException("Empty stack.");
} else {
int nrOfItemsInFirst = first.Count;
T[] reverser = new T[nrOfItemsInFirst];
// Reverse first
for (int i = 0; i < nrOfItemsInFirst; i++)
reverser[i] = first.Dequeue();
for (int i = nrOfItemsInFirst - 1; i >= 0; i--)
first.Enqueue(reverser[i]);
// Append second to first
while (second.Count > 0)
first.Enqueue(second.Dequeue());
// Swap first and second
Queue<T> temp = first; first = second; second = temp;
return second.Dequeue();
}
}
}
विश्लेषण
स्पष्ट रूप से पुश समय में काम करता है । पॉप और समय के भीतर सब कुछ छू सकता है , इसलिए हमारे पास सबसे खराब स्थिति में है। एल्गोरिथ्म इस व्यवहार (उदाहरण के लिए) को प्रदर्शित करता है यदि कोई स्टैक पर तत्वों को धकेलता है और फिर बार-बार एक एकल पुश और उत्तराधिकार में एक एकल पॉप ऑपरेशन करता है।O(1)firstsecondO(n)n
दूसरा एल्गोरिथ्म
हमारी दो कतारें हैं: कतार और कतार । हमारी 'पुश कतार' होगी , जबकि 'स्टैक ऑर्डर' में पहले से मौजूद कतार होगी।firstsecondfirstsecond
यह पहली एल्गोरिथ्म, जिसमें हम तुरंत 'फेरबदल' की सामग्री को नहीं है की एक अनुकूलित संस्करण है में । इसके बजाय, यदि की तुलना में तत्वों की एक पर्याप्त रूप से छोटे संख्या में शामिल (अर्थात् में तत्वों की संख्या का वर्गमूल ), हम केवल पुनर्निर्माण ढेर क्रम में और के साथ मर्ज नहीं है ।firstsecondfirstsecondsecondfirstsecond
- पुश करना अभी भी पैरामीटर पर केवल एनक्यूइंग करके किया जाता है ।first
- पोपिंग निम्नानुसार किया जाता है। यदि खाली है, तो हम बस धोखा देते हैं और परिणाम वापस करते हैं। अन्यथा, हम की सामग्री को पुनर्गठित कर रहे हैं ताकि वे स्टैक ऑर्डर में हों। यदि हम बस धोखा देते हैं और परिणाम वापस करते हैं। अन्यथा, हम संलग्न पर , स्वैप और विपंक्ति, और परिणाम लौटने।firstsecondfirst|first|<|second|−−−−−−−√firstsecondfirstfirstsecondsecond
पहली एल्गोरिथ्म के लिए सी # कोड
यह काफी पठनीय होना चाहिए, भले ही आपने पहले कभी C # नहीं देखा हो। यदि आप नहीं जानते हैं कि जेनेरिक क्या हैं, तो स्ट्रिंग्स के ढेर के लिए, अपने दिमाग में 'टी' के सभी उदाहरणों को बदलें।
public class Stack<T> {
private Queue<T> first = new Queue<T>();
private Queue<T> second = new Queue<T>();
int unsortedPart = 0;
public void Push(T value) {
unsortedPart++;
first.Enqueue(value);
}
public T Pop() {
if (first.Count == 0) {
if (second.Count > 0)
return second.Dequeue();
else
throw new InvalidOperationException("Empty stack.");
} else {
int nrOfItemsInFirst = first.Count;
T[] reverser = new T[nrOfItemsInFirst];
for (int i = nrOfItemsInFirst - unsortedPart - 1; i >= 0; i--)
reverser[i] = first.Dequeue();
for (int i = nrOfItemsInFirst - unsortedPart; i < nrOfItemsInFirst; i++)
reverser[i] = first.Dequeue();
for (int i = nrOfItemsInFirst - 1; i >= 0; i--)
first.Enqueue(reverser[i]);
unsortedPart = 0;
if (first.Count * first.Count < second.Count)
return first.Dequeue();
else {
while (second.Count > 0)
first.Enqueue(second.Dequeue());
Queue<T> temp = first; first = second; second = temp;
return second.Dequeue();
}
}
}
}
विश्लेषण
स्पष्ट रूप से पुश समय में काम करता है ।O(1)
पॉप काम करता है amortized समय में। दो मामले हैं: अगर , तब हम में क्रम में फेरबदल करते हैं समय। यदि , तो हमारे पास पुश के लिए कम से कम कॉल होना चाहिए था । इसलिए, हम केवल इस मामले को पुश और पॉप पर हर कॉल कर सकते हैं। इस मामले का वास्तविक समय चल रहा है , इसलिए परिशोधित समय ।O(n−−√)|first|<|second|−−−−−−−√firstO(|first|)=O(n−−√)|first|≥|second|−−−−−−−√n−−√n−−√O(n)O(nn√)=O(n−−√)
अंतिम नोट
पॉप को एक ऑपरेशन बनाने की लागत पर अतिरिक्त चर को समाप्त करना संभव है , पॉप करने के बजाय हर कॉल पर पुश करने के बजाय सभी काम करें।O(n−−√)first