Минимальное значение из стека

У меня есть стек, который содержит некоторые целочисленные данные. Я хочу найти минимальное значение из стека за O(1) времени. Есть идеи?

PS: нет упорядочения (увеличения/уменьшения) данных в стеке.

спасибо,

Нэвин

7 ответов


используйте два стека. Один-это данные, другой-минимумы. Когда вы нажимаете на стек данных, нажмите новый минимум на стек минимумов (новый минимум-это минимум элемента, который вы нажимаете, и все, что в настоящее время находится в верхней части стека минимумов), а когда вы всплываете, выскакивают из обоих стеков (так что два стека всегда имеют одинаковое количество элементов). Чтобы найти минимальный элемент, просто посмотрите на верхнюю часть стека минимумов.

нажимая, хлопая и находя минута значение O (1).


O (n) - лучшее, что вы собираетесь сделать-вам нужно будет проверить каждое из значений и сравнить их с минимумом агрегатора, иначе как бы вы узнали, что у вас самый низкий?

Если вы хотите, вы можете сохранить минимум по мере добавления значений, что делает толчки более дорогими в интересах чтения O(1) (предварительно вычисленного минимума), но это все.


стек по определению push/pop (LIFO) структуры данных. Вы не можете использовать один стек!


Я не уверен, почему вы планируете сделать это в постоянное время для произвольной длины. Лучшее, что вы сможете сделать, это O (n)


вы, вероятно, хотите какой-то приоритет кучи Если вы хотите всегда всплывать наименьший элемент. Если вы хотите открыть то, что было последним, но сможете узнать порядок элементов, оставшихся в стеке, какое-то дерево поиска, например красный-черный будет поддерживать удаление элемента из произвольной позиции (ваш стек будет иметь указатель на узел дерева, поэтому, когда вы поп, вы можете его найти).

Если вам нужно только знать минимум (или максимум) оставаясь в стеке, то ESRogs ' является оптимальным.


вот реализация алгоритма ESRogs на Python с использованием списков в виде стеков:

class ConstantStack:
    def __init__(self):
        self.stack = []
        self.min_stack = []
    def push(self,item):
        self.stack.append(item)
        if len(self.min_stack) == 0:
            self.min_stack.append(item)
            return
        # Get the smaller item between the pushed item and the top of the stack
        smallest = min(item,self.min_stack[-1])
        self.min_stack.append(smallest)
    def pop(self):
        self.min_stack.pop()
        return self.stack.pop()
    def min(self):
        # NOTE: min_stack[-1] is equivalent to peek()
        return self.min_stack[-1]

вот пример его использования:

>>> s = ConstantStack()
>>> s.push(3)
>>> s.push(7)
>>> s.push(6)
>>> s.push(1)
>>> s.min()
1
>>> s.pop()
1
>>> # Now that 1 is gone, 3 is the next smallest
>>> s.min()
3
>>> s.pop()
6
>>> # 6 was popped but 3 still remains the smallest
>>> s.min()
3
>>> s.pop()
7
>>> s.min()
3
>>> s.pop()
3

#define STACKSIZE 50

typedef struct stack
{
    int item[STACKSIZE];
    int top;
}MULSTACKEX;

void InitStack(MULSTACKEX &st)
{
   st.item[STACKSIZE] = 0;
   st.top = -1;
}

void Push(MULSTACKEX &st1, MULSTACKEX &st2, int elem)
{
    if(st1.top == -1)
    {   
        st1.top++;
        st1.item[st1.top] = elem;

        st2.top++;
        st2.item[st2.top] = elem;
    }
    else
    {
        st1.top++;
        st1.item[st1.top] = elem;

        if(elem < st2.item[st2.top])
        {
            st2.top++;
            st2.item[st2.top] = elem;
        }
    }
}

void Display(MULSTACKEX &st1, MULSTACKEX &st2)
{
    cout<<"stack1 elements: "<<endl;
    for(int i = 0; i <= st1.top; i++)
    {
        cout<<st1.item[i]<<"->";
    }

    cout<<endl;
    cout<<"stack2 elements: "<<endl;
    for(int i = 0; i <= st2.top; i++)
    {
        cout<<st2.item[i]<<"->";
    }

}

int Pop(MULSTACKEX &st1, MULSTACKEX &st2)
{
    int elem = 0;
    if(st1.item[st1.top] == st2.item[st2.top])
    {
        elem = st2.item[st2.top];
        st2.top--;

        elem = st1.item[st1.top];
        st1.top--;
    }
    else
    {
        elem = st1.item[st1.top];
        st1.top--;
    }

    return elem;    
}
int FindMin(MULSTACKEX &st2)
{
    int elem = st2.item[st2.top];
    return elem;
}

int _tmain(int argc, _TCHAR* argv[])
{
    MULSTACKEX stack1, stack2;

    InitStack(stack1); 
    InitStack(stack2);


    Push(stack1,stack2,13); 
    Push(stack1,stack2,17);
    Push(stack1,stack2,5);
    Display(stack1,stack2);

    int min_elem1 = FindMin(stack2);
    cout<<"Min element in the list is: "<<min_elem1<<endl<<endl;

    int deletedelem2 = Pop(stack1,stack2);
    cout<<"Pop element from the stack:"<< deletedelem2 <<endl<<endl;
    Display(stack1,stack2);

    cout<<endl<<endl;

    Push(stack1,stack2,19);
    Push(stack1,stack2,8);
    Display(stack1,stack2);

    cout<<endl<<endl;

    int deletedelem1 = Pop(stack1,stack2);
    cout<<"Pop element from the stack:"<< deletedelem1 <<endl<<endl;
    Display(stack1,stack2);

    int min_elem2 = FindMin(stack2);
    cout<<"Min element in the list is: "<<min_elem2<<endl<<endl;

    return 0;
}