[堆栈]堆栈算法分析总结

包含min函数的栈

这个题目就是让实现一个新的栈,但是这个栈额外的增加一个函数,那就是min这个获得栈中元素最小值的函数。刚看到这个题目可能忽然想到用一个变量记录栈中元素的最小值,但是当栈中的这个最小元素被pop之后,谁又是最小值呢?

于是想着用一个和栈一样大小的数组记录每个栈元素作为栈顶元素的时候,栈中的最小值。但是不好维护,索性用一个辅助栈记录数据栈中每个元素如果作为栈顶元素的时候,数据栈中的最小值。这样数据栈和辅助栈中的元素个数时刻相等,区别仅仅是每次push的时候,数据栈压参数,辅助栈压参数和当前最小值中的一个。

但是真的要数据栈和辅助栈中的元素个数相同吗?不一定,辅助栈只要维护这样一种状态就ok了:辅助栈的栈顶元素而言,只要数据栈中相等的那个数比它上面的所有的数小就好了。当然了,两个相同的最小值要在辅助栈中压栈两次,不然数据栈pop的时候无法判断下一个元素是否还是最小值(两个或多个最小值连在一起),导致不能确定辅助栈要不要pop。

对于push入栈函数:
直接在数据栈中push(x),但是辅助栈中入栈是有条件的:
	1.辅助栈为空
	2.参数x的值小于或者等于辅助栈的栈顶元素

对于pop弹栈函数:
首先如果数据栈为空,弹栈作废。
如果数据栈不为空,
	1.数据栈栈顶元素大于辅助栈顶元素,数据栈自己弹栈
	2.数据栈栈顶元素等于辅助栈顶元素,数据栈和辅助栈都弹栈
	3.数据栈栈顶元素小于辅助栈顶元素,不可能存在

  代码实现:

class MinStack {
public:
    void push(int x) 
    {
        _stack.push(x);
        if(_minStack.empty() || x <= _minStack.top())
        {
            _minStack.push(x);
        }
    }

    void pop() 
    {
        if(!_stack.empty())
        {
            if(_stack.top() == _minStack.top())
            {
                _minStack.pop();
            }
            
            _stack.pop();
        }
    }

    int top() 
    {
        if(!_stack.empty())
        {
            return _stack.top();
        }
        
        return 0;
    }

    int getMin() 
    {
        if(!_minStack.empty())
        {
            return _minStack.top();
        }
        return 0;
    }
    
private:
    stack<int> _stack;
    stack<int> _minStack;
};

两个栈实现一个队列

这个没有难点,直接代码:

class Solution
{
public:
    void push(int node) 
    {
        stack1.push(node);
    }

    int pop() 
    {
        int result = 0;
        if(!stack2.empty())
        {
            result = stack2.top();
            stack2.pop();
        }//if
        else
        {
            while(!stack1.empty())
            {
                stack2.push(stack1.top());
                stack1.pop();
            }
            result = stack2.top();
            stack2.pop();
        }
        
        return result;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

两个队列实现一个栈

这个好像没有上面的那个简单 ,但是要记住一点,不管队列还是栈,他们都是能够根据size()函数求出来具体的长度,都是能够遍历的。所以代码实现:

class Stack 
{
public:
    // Push element x onto stack.
    void push(int x) 
    {   
        q2.push(x);
        while(q2.size() > 1)
        {
            q1.push(q2.front());
            q2.pop();
        }//while
    }

    // Removes the element on top of the stack.
    void pop() 
    {   
        top();
        if(!q2.empty())
            q2.pop();
    }

    // Get the top element.
    int top() 
    {
        if(q2.empty())
        {
            for(int i = 0; i < q1.size() - 1; i++)
            {
                q1.push(q1.front());
                q1.pop();
            }//for
            q2.push(q1.front());
            q1.pop();
        }//if
        
        return q2.front();
    }

    // Return whether the stack is empty.
    bool empty() 
    {
        return q1.empty() && q2.empty();
    }
private:
    queue<int> q1;
    queue<int> q2;
};

  

 

  

原文地址:https://www.cnblogs.com/stemon/p/4743975.html