Aşağıdaki cevap 'hiledir', çünkü işlemler arasında herhangi bir boşluk kullanmazken, işlemlerin kendisi alanından daha fazlasını kullanabilir . Bu problemi olmayan bir cevap için bu konudaki başka bir yere bakın.O(1)
Ben gerçekten sorunuza bir cevap yok, ben çalışan bir algoritma buldunuz O(n)yerine zaman. Kanıt olmamasına rağmen, bunun sıkı olduğuna inanıyorum. Herhangi bir şey varsa, algoritmaO(n) 'nindaha düşük bir sınırını kanıtlamaya çalışmanınfaydasız olduğunu gösterir, bu nedenle sorunuzu yanıtlamanıza yardımcı olabilir.O(n−−√)O(n)O(n)
İki algoritma veriyorum, birincisi Pop için çalışma zamanı ve ikincisi O ( √ ) olan basit bir algoritmaO(n)Pop için koşu zamanı. Birincisini esas olarak sadeliği nedeniyle, ikincisini anlaması daha kolay olacak şekilde tanımlarım.O(n−−√)
Daha fazla ayrıntı vermek gerekirse, ilki ek alan yoktur, en kötü durum (ve itfa edilmiş) İtme ve O ( n ) en kötü durum (ve itfa edilmiş) Pop vardır, ancak en kötü durum davranış her zaman tetiklenmez. İki kuyruğun ötesinde herhangi bir boşluk kullanmadığından, Ross Snider tarafından sunulan çözümden biraz 'daha iyi'.O(1)O(n)
İkincisi, tek bir tamsayı alanı kullanır (yani fazladan boşluk), O ( 1 ) en kötü durumda (ve itfa edilmiş) Push ve O ( √O(1)O(1)itfa edilmiş Pop. Bu nedenle çalışma süresi, 'basit' yaklaşımdan önemli ölçüde daha iyidir, ancak biraz daha fazla alan kullanır.O(n−−√)
İlk algoritma
İki sıraları vardır: sıra ve sıra s e c O , n d . f i r s t ise, bizim itme sıra "olacaktır s e c O , n d zaten 'yığın sırada' sıra olacaktır.firstsecondfirstsecond
- Sadece üzerine parametrenin kuyruğa alınmasından yapılır itme .first
- Haşhaş şu şekilde yapılır. Eğer , basitçe sıradan çıkarma boş s e c O , n d sonucu döndürür. Aksi takdirde, geri f ı r s t , tüm ekleme s e c O , n d için f ı r s t ve takas f ı r s t ve s e c O , n d . Daha sonra sıradan çıkarma s e c Ofirstsecondfirstsecondfirstfirstsecond ve dequeue sonucunu döndürür.second
İlk algoritma için C # kodu
Daha önce hiç C # görmemiş olsanız bile, bu oldukça okunaklı olabilir. Jeneriklerin ne olduğunu bilmiyorsanız, sadece 'T' örneklerini zihninizde 'string' ile değiştirin, bir dizi dizge için.
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();
}
}
}
analiz
O(1)firstsecondO(n)n
İkinci algoritma
İki sıraları vardır: sıra f ı r s t ve sıra s e c O , n d . f i r s t ise, bizim itme sıra "olacaktır s e c O , n dfirstsecondfirstsecond
firstsecondfirstsecondsecondfirstsecond
- first
- firstsecondfirst|first|<|second|−−−−−−−√firstsecondfirstfirstsecondsecond
İlk algoritma için C # kodu
Daha önce hiç C # görmemiş olsanız bile, bu oldukça okunaklı olabilir. Jeneriklerin ne olduğunu bilmiyorsanız, sadece 'T' örneklerini zihninizde 'string' ile değiştirin, bir dizi dizge için.
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();
}
}
}
}
analiz
O(1)
O(n−−√)|first|<|second|−−−−−−−√firstO(|first|)=O(n−−√)|first|≥|second|−−−−−−−√n−−√n−−√O(n)O(nn√)=O(n−−√)
Son not
O(n−−√)first