day10|栈与队列01

232.用栈实现队列

题目:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false。

思路及代码:

1.用栈实现队列(先进先出),需要用到两个栈,一个栈stackIn用来接收进来的元素,一个栈stackOut用来将元素弹出。

2.代码如下:

class MyQueue {
public:
    stack<int> stackIn;
    stack<int> stackOut;

    MyQueue() {

    }
    
    void push(int x) {
        stackIn.push(x);
    }
    
    int pop() {
        if(stackOut.empty()){
            while(! stackIn.empty()){
                stackOut.push(stackIn.top());
                stackIn.pop();
            }
        }
        int result = stackOut.top();
        stackOut.pop();  //pop()方法确实只做弹出操作,并不返回被弹出的元素的值
        return result;
    }
    
    int peek() {
        int result = this -> pop();
        stackOut.push(result);
        return result; 
    }
    
    bool empty() {
        return stackIn.empty() && stackOut.empty();
    }
};

时间复杂度:push和empty 为O(1),pop和peak 为O(n)

空间复杂度: O(n)

        这是因为我们使用了两个栈stackInstackOut来模拟队列的行为。在最坏的情况下,如果所有元素都在stackIn中,那么空间复杂度就是O(N)。即使我们将stackIn中的元素转移到stackOut中以便执行poppeek操作,空间复杂度仍然是O(N),因为我们需要额外的空间来存储这些元素。

        值得注意的是,虽然栈本身在内存中是以连续的方式存储的,但这里我们考虑的是整个队列数据结构占用的空间,包括两个栈中存储的元素。因此,即使栈本身的空间复杂度是O(1)(因为它们是固定大小的数据结构),但在这个特定的MyQueue实现中,整个队列的空间复杂度是O(N)。

        空间复杂度通常用于描述数据结构或算法在执行过程中所使用的额外空间量。对于栈这种数据结构,其空间复杂度取决于栈中存储的元素数量。

补充:

        如果容器中有一个元素,其空间复杂度是O(1),如果有n个元素,空间复杂度就是O(n)吗? 

        是的。空间复杂度描述的是数据结构或算法在执行过程中所使用的额外空间量,它通常与输入数据的大小(即元素的数量)有关。

  • 当容器(如栈、队列、数组、链表等)中只有一个元素时,其空间复杂度是O(1)。这是因为无论输入数据的大小如何变化,存储一个元素所需的空间是固定的,不会随着输入规模的增大而增大。
  • 当容器中有n个元素时,其空间复杂度是O(n)。这是因为容器需要为这n个元素分配空间,所需的空间量随着元素数量的增加而线性增长。

需要注意的是,这里的O(n)或O(1)描述的是空间复杂度的上界。在实际应用中,可能还有其他因素(如指针、索引等)会影响空间复杂度,但这些通常不会改变复杂度的主要阶数。

因此,对于任何容器或数据结构,其空间复杂度通常取决于存储的元素数量。如果元素数量是固定的,则空间复杂度是O(1);如果元素数量是变量,则空间复杂度通常是O(n),其中n是元素的数量。


225. 用队列实现栈 

题目:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false。

思路及代码:

1.利用一个队列实现。循环队列。弹出元素时,将除了最后一个元素之外的元素循环加入到队列的尾部,然后将最后一个元素弹出。

代码如下:

class MyStack {
public:
    queue<int> que;
    MyStack() {

    }
    
    void push(int x) {
        que.push(x);
    }
    
    int pop() {
        int size = que.size();
        size --; //队列索引从0开始,保留最后一个元素,保证从队的第一个元素开始,一直到倒数第二个元素结束
        while(size--){
            que.push(que.front());
            que.pop();
        }
        int result = que.front();
        que.pop();
        return result;
    }
    
    int top() {
        return que.back(); //直接返回que的最后一个元素
    }
    
    bool empty() {
        return que.empty();
    }
};

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

空间复杂度:O(n) 

2.也可以用两个队列去实现栈的功能,que1和que2,其中,que2是辅助队列,主要起到备份的作用。

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值