【剑指offer第一题】用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

昨天笔试了两道题,在牛客网,看到核心代码考核的时候,我整个人都傻了……这是个什么模式。
找到了这个剑指offer,甚至发现了昨天笔试的原题,QWQ,唉注定过不了。
定个小目标,七天刷二十道左右,一天两道,应该不是很难,先从简单的开始。
第一个选定的时候栈模拟队列,不算难,主要是复习一下知识吧,毕竟好久没编了,手生。

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

有参考网上大佬的各类文章,其中:https://blog.csdn.net/cherrydreamsover/article/details/80466781
讲得最为清晰。

首先明白栈和队列的区别:

  1. 栈:先进后取,类似如一个桶,你只能拿你最后放入进去的东西。
  2. 队列:先进先出,类似于排队打饭,只有最前面人才能最先打饭后离开队伍。

如果,用两个栈模拟队列的思想就出来了。
设立两个栈(原题给出,核心代码好像都会规定好?)

stack<int> stack1;
stack<int> stack2;

其中,stack1作为数据插入的一个栈,而stcak2则是真正的容器。
也就是说,将数据从stack1存入,然后反向倒进stack2当中,这样虽然栈本身的性质没有改变,但是数据的排列顺序改变了,因此实现了队列的‘先进先出’。
举例子,比如一开始的输入数据是1,2,3,4。

 stack1.push(node);

那么首先要把数据输入到stack1中存储为正常的:1,2,3,4;
然后使用stcak.top()将4,怼到stack2中,然后再将4进行删除操作。
再循环,将3怼到stack2中,再把三循环。
最后得到的两个栈。
stack1:
stack2:4,3,2,1
这样再提取出来就是1,2,3,4队列的顺序了。

 if(stack2.empty())
        {
            while(!stack1.empty())
            {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }

在操作过程当中要注意stack2是否为空,否则就会乱套。

代码实现如下:

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

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

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

然后就是我所找到的那个博文提到的扩展知识。
如果何用两个队列伪装成栈。
这个想法也很巧妙,就是将除了最后一个元素的元素,全部挪到另外一个队列中,然后再将剩下的队列元素删除,将有元素的这个队列看做主队列,就完成了‘后进后出’的操作。
贴一下原文代码。
这个比栈多一个就是要两个队列来回倒腾。

template<typename T> class CStack
{
public:
	CStack(void);
	~CStack(void);
 
	void appendTail(const T& node);
	T deleteHead();
 
private:
	queue<T> q1;
	queue<T> q2;
};
 
template<typename T>
void CStack<T>::appendTail(const T& node)//实现栈元素的插入
{
	//数据的插入原则:保持一个队列为空,一个队列不为空,往不为空的队列中插入元素
	if (!q1.empty())
	{
		q1.push(node);
	}
	else
	{
		q2.push(node);
	}
}
 
template<typename T>
T CStack<T>::deleteHead()//实现栈元素的删除
{
	int ret = 0;
	if (!q1.empty())
	{
		int num = q1.size();
		while (num > 1)
		{
			q2.push(q1.front());
			q1.pop();
			--num;
		}
		ret = q1.front();
		q1.pop();
	}
	else
	{
		int num = q2.size();
		while (num > 1)
		{
			q1.push(q2.front());
			q2.pop();
			--num;
		}
		ret = q2.front();
		q2.pop();
	}
	return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值