РЕДАКТИРОВАТЬ: Это не проходит ограничение «постоянное пространство» - это в основном удваивает требуемое пространство Я очень сомневаюсь, что есть решение, которое не делает это, хотя, не разрушая сложность среды выполнения (например, делая push / pop O (n)). Обратите внимание, что это не меняет сложность требуемого пространства, например если у вас есть стек с O (n) требованиями к пространству, это все равно будет O (n) только с другим постоянным коэффициентом.
Решение с непостоянным пространством
Сохраните «дубликат» стека «минимум всех значений ниже в стеке». Когда вы вытаскиваете основной стек, вынимайте и минимальный стек. Когда вы загружаете основной стек, нажмите либо новый элемент, либо текущий минимум, в зависимости от того, что меньше. getMinimum()
затем реализуется как просто minStack.peek()
.
Итак, используя ваш пример, мы получили бы:
Real stack Min stack
5 --> TOP 1
1 1
4 2
6 2
2 2
После двойного щелчка вы получите:
Real stack Min stack
4 2
6 2
2 2
Пожалуйста, дайте мне знать, если этой информации недостаточно. Это просто, когда ты делаешь это, но сначала может потребоваться немного почесать голову:)
(Недостатком, конечно, является то, что он удваивает требования к пространству. Время выполнения не сильно страдает, хотя - то есть это все та же сложность.)
РЕДАКТИРОВАТЬ: есть вариант, который немного более неудобно, но в целом имеет больше места. У нас все еще есть минимальный стек, но мы извлекаем его только тогда, когда значение, которое мы извлекаем из основного стека, равно значению в минимальном стеке. Мы только помещаем в минимальный стек, когда значение, помещаемое в основной стек, меньше или равно текущему минимальному значению. Это позволяет дублировать минимальные значения. getMinimum()
- это всего лишь операция просмотра. Например, взяв оригинальную версию и снова нажав 1, мы получим:
Real stack Min stack
1 --> TOP 1
5 1
1 2
4
6
2
Выскакивает из вышеперечисленных хлопков из обоих стеков, потому что 1 == 1, оставляя:
Real stack Min stack
5 --> TOP 1
1 2
4
6
2
Снова всплывающее окно только выскакивает из основного стека, потому что 5> 1:
Real stack Min stack
1 1
4 2
6
2
Снова всплывают оба стека, потому что 1 == 1:
Real stack Min stack
4 2
6
2
Это приводит к той же сложности пространства наихудшего случая (удвоение исходного стека), но гораздо лучшему использованию пространства, если мы редко получаем «новый минимум или равенство».
РЕДАКТИРОВАТЬ: Вот реализация злой схемы Пита. Я не проверил это полностью, но я думаю все в порядке:)
using System.Collections.Generic;
public class FastMinStack<T>
{
private readonly Stack<T> stack = new Stack<T>();
// Could pass this in to the constructor
private readonly IComparer<T> comparer = Comparer<T>.Default;
private T currentMin;
public T Minimum
{
get { return currentMin; }
}
public void Push(T element)
{
if (stack.Count == 0 ||
comparer.Compare(element, currentMin) <= 0)
{
stack.Push(currentMin);
stack.Push(element);
currentMin = element;
}
else
{
stack.Push(element);
}
}
public T Pop()
{
T ret = stack.Pop();
if (comparer.Compare(ret, currentMin) == 0)
{
currentMin = stack.Pop();
}
return ret;
}
}