DAY10: 栈和队列入门(232、225栈和队列的相互实现)

理论基础

栈和队列是STL(C++标准库)里面的两个数据结构。队列queue:先进先出,栈stack:先进后出。

栈提供push和pop等接口,所有元素必须符合先进后出规则,无法像set和map一样提供迭代器iterator来遍历所有元素。但我们可以控制使用哪种容器来实现栈的功能,栈的内部实现可以是vector、deque、list都可以,主要是数组和链表的底层实现。

我们常使用SGI STL,如果没有指定底层实现的话,默认以deque(双向队列)为底层结构。

初始化

std::stack > third;//指定vector为栈的底层实现,初始化stack
std::queue> third;//指定list为底层实现,初始化queue

关于栈和队列的相关操作

  • push(x) 将的元素放入
  • pop() 移除元素
  • peek() 返回首部的元素,是一个查询操作
  • empty() 返回是否为空

Leetcode: 232 用栈来实现队列

因为队列是先进先出,而栈是先进后出,因此可以想到使用两个栈来实现队列的操作。先入栈,然后在进入一个栈来反转元素,然后出栈。

注意点:在pop的时候,需要判断输出栈为空的话,需要将进栈数据全部导入进来,再从出战弹出数据,不然出站的顺序会乱。如果进栈和出栈都为空的话,说明模拟的队列为空。

时间复杂度 push\empty为O(1),pop\peek为O(N)

空间复杂度为O(N)

具体实现的相关细节如下:

class MyQueue {
public:
    stack stackin;//初始化栈
    stack stackout;
    MyQueue() {

    }
    
    void push(int x) {
        stackin.push(x);

    }
    
    int pop() {
        //如果当前stackout队列为空,才能从stackin里面导入数据
        if(stackout.empty()){
            while(!stackin.empty()){//从stackin中导入数据直到为空
                stackout.push(stackin.top());//将stackin中的头元素导出的数据加到stackout中
                stackin.pop();//数据加入之后再pop掉
            }
        }
        int result = stackout.top();
        stackout.pop();
        return result;
    }
    
    int peek() {//查询队列开头的函数
        int res = this -> pop();//直接使用已有的pop函数,注意这个pop是我们上面定义的pop函数
        stackout.push(res);//因为只是查询操作,因此需要塞回去
        return res;
    }
    
    bool empty() {//队列的empty函数,判断条件为stackin stackout都为空
        return stackin.empty() && stackout.empty();


    }
};

Leetcode: 225 用队列实现栈

使用两个队列来实现栈

和上一题不同,第二个队列的作用完全是用来备份数据,队列1输入N个数据,然后输出N-1个数据到队列2中,然后队列1输出最后一个数据,然后再将队列2中的数据复制回队列1,从而实现一个栈的功能。

使用一个队列来实现栈

但实际上只使用一个队列就可以实现栈,只要将N-1个数据输出,然后再从头入队列,输出队列里原本的N数据就可以。

时间复杂度: pop为O(n),其他为O(1)

空间复杂度: O(n)

代码如下,非常建议和前面那道题配合起来看:

class MyStack {
public:
    queue que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);

    }
    
    int pop() {
        int size = que.size();//计算队列的大小
        size--;//减少size然后循环的时候就能不动最后的一个数据
        while(size--){
            que.push(que.front());
            que.pop();
        }
        int result = que.front();
        que.pop();
        return result;
    }
    
    int top() {
        return que.back();

    }
    
    bool empty() {
        return que.empty();

    }
};

总结

第一次接触栈和队列的题目,先熟悉基本操作和逻辑,之后继续攻克更难的题目。DAY9的题目还在整理,先把DAY10的知识放出来:)

你可能感兴趣的:(leetcode刷题系列,leetcode,c++,笔记)