剑指offer 栈_队列类题目

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014303647/article/details/82051651

1:用两个栈实现队列

题目:
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

解析:题目中有两个栈stack1和stack2,用来模拟队列的操作,我是想把第一个stack1作为数据存储,第二个stack2作为中转。队列的特点是先进先出,
1:入队操作,因为用stack1作为存储,首先得判断上一次stack2的数据又放回去没,一进一出stack1刚好维持原有。
时间复杂度为O(n)。
2:出队操作, 因为先进先出,那么最开始进入队列的元素肯定在栈底,所以可以将stack1的元素全部中转到stack2,那么在stack2中最上面的元素就是最开始入队的元素。时间复杂度为O(n)。

代码:

class Solution
{
public:
    void push(int node) 
    {
        while(!stack2.empty())
        {
            int top = stack2.top();
            stack2.pop();
            stack1.push(top);
        }
        stack1.push(node);
    }

    int pop() 
    {
        int last;
        while(!stack1.empty())
        {
            int val = stack1.top();
            stack2.push(val);
            stack1.pop();
        }
        int top = stack2.top();
        stack2.pop();
        return top;
    }

private:
    stack<int> stack1; //作为存储数据
    stack<int> stack2; //进行中转
};

2:包含min函数的栈

题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

解析:
首先得定义一个栈ss,然后在这个栈上定义操作。然后定义一个辅助栈help,来维护入栈的所有元素的最小值,这个栈肯定是单调递增的。然后对于栈的各种操作。

1:入栈操作,入栈的时候,得维护那个辅助栈,如果入栈的元素比辅助栈的栈顶元素小,说明要入栈的元素为当前栈中所有元素的最小值。

2:出栈操作,当把栈中元素出栈时,得和辅助栈help的栈顶元素相比,如果相等,那么辅助栈的栈顶元素出栈。

3:取最小值元素,直接取辅助栈的栈顶元素即是当前栈中的最小元素。

这样取最小值的时间复杂度为O(1),我们采取了空间换时间的做法。

代码:

class Solution {
public:
    stack<int>ss;
    stack<int>help;
    void push(int value) 
    {
        if(!help.empty())
        {
            int cur_min_value = help.top();
            if(value<=cur_min_value) help.push(value);
            ss.push(value);
        }
        else 
        {
            ss.push(value);
            help.push(value);
        }
    }
    void pop() 
    {
        int top_ss_value = ss.top();
        int top_help_value = help.top();
        if(top_ss_value==top_help_value)
        {
            ss.pop();
            help.pop();
        }
        else ss.pop();
    }
    int top() 
    {
        return ss.top();
    }
    int min() 
    {
        int min_value = help.top();
        return min_value;
    }
};

3:栈的压入、弹出序列

题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解析:可以使用栈进行模拟入栈出栈的操作,比如如果入栈以后,栈顶元素和popV的当前元素相同,说明这个序列可以出栈,直到当前入栈元素和popV的当前元素不相同为止,最后如果栈为空,说明出栈序列是合法的,如果不为空,那么出栈序列就是不合法的。

代码:

#include "stdafx.h"
#include<iostream>
#include<vector>
#include <initializer_list>
#include<stack>
using namespace std;


bool IsPopOrder(vector<int> pushV, vector<int> popV)
{
    stack<int>st;
    while (!st.empty())  st.pop();
    int vec_size = pushV.size();
    int pop_index = 0;
    for (int i = 0; i<vec_size; i++)
    {
        st.push(pushV[i]);
        cout << st.top() << " "<< st.size()<< endl;
        while (st.top() == popV[pop_index])
        {
            //cout << st.size() << ends;
            st.pop();
            ++pop_index;
            if (st.empty())  break;
        }
    }
    cout << st.size() << endl;
    return st.empty() ? true : false;
}


int main()
{
    initializer_list<int> lst1 = { 1, 2, 3, 4, 5 };
    initializer_list<int> lst2 = { 4, 3, 5, 1, 2 };
    vector<int>pushV(lst1);
    vector<int>popV(lst2);
    cout << IsPopOrder(pushV, popV);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u014303647/article/details/82051651