c语言栈和队列编程题,leetcode c语言题解(4)——栈和队列互相实现的优化版

栈和队列互相实现

FIFO和FILO,相当于+-号,互转都是利用“负负得正”的原理。

1. 栈实现队列

官方解答中第二种思路很6,按需反转,这样摊还分析下来,复杂度变成了O(1)

class MyQueue {

private:

stack s1;

stack s2;

public:

/** Initialize your data structure here. */

MyQueue() {}

/** Push element x to the back of queue. */

void push(int x) {

s1.push(x);

}

/** Removes the element from in front of queue and returns that element. */

int pop() {

int ret=0;

notempty:

if(!s2.empty()){

ret = s2.top();

s2.pop();

return ret;

}

while(!s1.empty()){

s2.push(s1.top());

s1.pop();

}

//return pop();

goto notempty;

}

/** Get the front element. */

int peek() {

int ret=0;

notempty:

if(!s2.empty()) return s2.top();

while(!s1.empty()){

s2.push(s1.top());

s1.pop();

}

goto notempty;

}

/** Returns whether the queue is empty. */

bool empty() {

return s1.empty() && s2.empty();

}

};

2. 队列实现栈

官方解答中提供了三种思路,我用的方法和方法三很像,又同时做了一点点优化:

官方方法三

入栈O(N)

出栈O(1)

我的方法四 (其实思路一样, 就是pop时才去排序.)

入栈O(1)

出栈O(N),

方法四的优化

入栈O(1)

出栈: 最坏的情况O(N),最好的情况实际pop次数为0

缺点: 需要自定义结构体标记

2.1 方法四

class MyStack {

private:

queue buf;

public:

/** Initialize your data structure here. */

MyStack() {

}

/** Push element x onto stack. */

void push(int x) {

buf.push(x);

}

/** Removes the element on top of the stack and returns that element. */

int pop() {

int size = buf.size();

int ret = buf.back();

while(--size>=0){

if(size!=0) buf.push(buf.front());

buf.pop();

}

return ret;

}

/** Get the top element. */

int top() {

return buf.back();

}

/** Returns whether the stack is empty. */

bool empty() {

return buf.empty();

}

};

2.2 方法四的优化版

思路就是:

用自定义结构体中的flag成员标记当前队列中元素是否有效, 如果是false,则相当于已经被pop(实际并不用pop)

push直接添加,略

pop时

如果back().falg==true,我们直接修改其为false,标记其已经无效了

否则,说明倒数两个需要被删除, 按照单队列思路,头循环加到尾部,然后把最后两个都直接pop掉(因为最后一个已经被标记为false,而现在又pop一次,所以两个都直接pop)

top时,类似pop的处理方法

最坏的情况:连续pop,但是即使这样pop依然是O(N)

最好的情况: push一次,pop一次, 这样实际pop次数为0

混合情况: 优于单队列

typedef struct {

int val;

bool flag;

}myint;

class MyStack {

private:

queue buf;

public:

/** Initialize your data structure here. */

MyStack() {

}

/** Push element x onto stack. */

void push(int x) {

myint mx = {x, true};

buf.push(mx);

}

/** Removes the element on top of the stack and returns that element. */

int pop() {

if(buf.back().flag == true) {

buf.back().flag=false;

return buf.back().val;

}

int size = buf.size();

while(--size>=2){

buf.push(buf.front());

buf.pop();

}

int ret = buf.front().val;

buf.pop();

buf.pop();

return ret;

}

/** Get the top element. */

int top() {

if(buf.back().flag==true) return buf.back().val;

int size = buf.size();

while(--size>=1){

buf.push(buf.front());

buf.pop();

}

buf.pop();

return buf.back().val;

}

/** Returns whether the stack is empty. */

bool empty() {

return (buf.empty() || (!buf.front().flag));

}

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值