栈、队列系列

目录

 

剑指Offer(9)--用两个栈实现队列(用两个队列实现栈)

 剑指Offer(30)--包含min函数的栈 

 剑指Offer(31)--栈的压入、弹出序列

 剑指Offer(59)--队列的最大值

用数据结构模拟浏览器前进后退的操作


剑指Offer(9)--用两个栈实现队列(用两个队列实现栈)

思路:

当需要输出的时候,如果pop栈中有数据就直接输出栈顶元素,如果没有的话,将push栈中的数据全部倒入pop,然后将pop栈顶的数据输出。 

class TwoStacksQueue
{
public:
	void push(int obj);
	int poll();
	int peek();
private:
	stack<int> stackPush;
	stack<int> stackPop;
};
void TwoStacksQueue::push(int obj)
{
	stackPush.push(obj);
}
int TwoStacksQueue::poll()
{
	if (stackPush.empty() && stackPop.empty())
		return -1;
	if (stackPop.empty())
	{
		while (!stackPush.empty())
		{
			stackPop.push(stackPush.top());
			stackPush.pop();
		}
	}
	int temp = stackPop.top();
	stackPop.pop();
	return temp;
}
//看一下,并不需要取走
int TwoStacksQueue::peek()
{
	if (stackPush.empty() && stackPop.empty())
		return -1;
	if (stackPop.empty())
	{
		while (!stackPush.empty())
		{
			stackPop.push(stackPush.top());
			stackPush.pop();
		}
	}
	int temp = stackPop.top();
	return temp;
}

两个队列实现栈 

#include<iostream>
#include<queue>
using namespace std;
//如何仅用队列结构实现栈结构

class TwoQueuesStack {
public:
	void push(int obj);
	int pop();
	int peek();
private:
	queue<int> que;
	queue<int> help;
};
void TwoQueuesStack::push(int obj)
{
	que.push(obj);
}
int TwoQueuesStack::pop()
{
	if (que.empty())
		return -1;
	while (que.size() != 1)
	{
		help.push(que.front());
		que.pop();
	}
	int temp = que.front();
	que.pop();
	que.swap(help);
	return temp;
}

 剑指Offer(30)--包含min函数的栈 

定义栈的数据结构,请在该类型中实现一个能够得到栈的最下元素的min函数。在该栈中,调用min、push及pop的时间复杂度都为O(1)

思路:
准备两个栈,一个用于正常放置元素的栈data,另一个min栈存放当前最小元素,在压栈的过程中min栈随着data栈增长,压入
data栈的元素和min栈的栈顶比较,如果待压入的数比min栈的栈顶要小,那么min栈中也压这个数;否则,重复压入min栈的栈顶
弹出的时候,同步弹出即可

class MyStack {
public:
	void push(int obj);
	int pop();
	int getmin();
private:
	stack<int> stackMin;
	stack<int> stackData;
};
void MyStack::push(int obj)
{
	if (stackMin.empty() || obj < getmin())
		stackMin.push(obj);
	else
	{
		int min = stackMin.top();
		stackMin.push(min);
	}
	stackData.push(obj);
}
int MyStack::pop()
{
	if (stackData.empty())
		return -1;
	stackMin.pop();
	int temp = stackData.top();
	stackData.pop();
	return temp;
}
int MyStack::getmin()
{
	if (stackMin.empty())
		return -1;
	return stackMin.top();
}

 剑指Offer(31)--栈的压入、弹出序列

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

思路:

建立一个辅助栈s,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹出数字。

判断第二个序列待输出的数字是否是栈顶元素,如果不是,则从输入序列中依次输入栈中,如果一直没找到,则返回为false。

#include<iostream>
#include<stack>
using namespace std;
bool IsPopOrder(const int* Push, const int *Pop, int length)
{
	if (Push == nullptr || Pop == nullptr || length < 1)
		return false;
	const int* nextPush = Push;
	const int* nextPop = Pop;
	stack<int> sData;
	//只要弹出序列不为空,一直循环
	while (nextPop - Pop < length)
	{
		while (sData.empty() || sData.top()!=*nextPop)
		{
			//输入序列中没有元素了
			if (nextPush - Push == length)
				break;
			sData.push(*nextPush);
			++nextPush;
		}
		if (sData.top() != *nextPop)
			break;
		sData.pop();
		++nextPop;
	}
	if (sData.empty() && nextPop - Pop == length)
		return true;
	return false;
}

 剑指Offer(59)--队列的最大值

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}

vector<int> getMAXWindow(vector<int>vec, int w) {
	int len = vec.size();
	deque<int> q;
	vector<int> res;
	if (len <= 0 || w < 1 || len < w) {
		return res;
	}
	for (int i = 0; i < len; i++) {
		//往双端队列中加入元素
		while (!q.empty() && vec[q.back()] <= vec[i]) {
			q.pop_back();
		}
		q.push_back(i);
		//判断当前双端队列的头节点是否过期
		if (q.front() == i - w)
			q.pop_front();
		//当i的值超过w-1后,每次都需要收集当前的最大值
		if (i >= w - 1)
			res.push_back(vec[q.front()]);
	}
	return res;
}

用数据结构模拟浏览器前进后退的操作

我们使用两个栈,X 和 Y,我们把首次浏览的页面依次压入栈 X,当点击后退按钮时,再依次从栈 X 中出栈,并将出栈的数据依次放入栈 Y。
当我们点击前进按钮时,我们依次从栈 Y 中取出数据,放入栈 X 中。当栈 X 中没有数据时,那就说明没有页面可以继续后退浏览了。当栈 Y 中没有数据,那就说明没有页面可以点击前进按钮浏览了

比如你顺序查看了 a,b,c 三个页面,我们就依次把 a,b,c 压入栈,这个时候,两个栈的数据就是这个样子:

你通过浏览器的后退按钮,从页面 c 后退到页面 a 之后,我们就依次把 c 和 b 从栈 X 中弹出,并且依次放入到栈 Y。这个时候,两个栈的数据就是这个样子:

这个时候你又想看页面 b,于是你又点击前进按钮回到 b 页面,我们就把 b 再从栈 Y 中出栈,放入栈 X 中。此时两个栈的数据是这个样子:

这个时候,你通过页面 b 又跳转到新的页面 d 了,页面 c 就无法再通过前进、后退按钮重复查看了,所以需要清空栈 Y。此时两个栈的数据这个样子:

找出数组中每个数的右边第一个比它大的数

vector<int> findMax(vector<int> num)
{ 
    if(num.size()==0)
        return num;
    vector<int> res(num.size());
    int i=0;
    stack<int> s;
    while(i<num.size())
    {
        if(s.empty()||num[s.top()]>=num[i])
        {
            s.push(i++);
        }
        else
        {
            res[s.top()]=num[i];
            s.pop();
        }
    }
    while(!s.empty())
    {
        res[s.top()]=INT_MAX;
        s.pop();
    }
    return res;
}

实现栈中元素排序

题目:将一个栈中的元素排序,借助另外一个栈!

思路:将排序的栈每次出栈一个元素,第一次直接放入缓冲栈中,第二开始直至结束,每个出栈元素都需要跟缓冲栈里面元素比较找到排序位置(缓冲栈这个时候也需要吐栈可以考虑把元素放回到排序栈中待会再放回来),直到所有元素排序完毕。

#include <iostream>
#include <stack>
void sortStack(stack<int>& InputStack)
{
    stack<int> Help;//定义一个暂时缓冲栈
    while (!InputStack.empty())
    {
        int CurValue = InputStack.top();
        InputStack.pop();
        while (!Help.empty() && CurValue > help.top())//在另外栈里面寻找插入位置
        {
            InputStack.push(Help.top());
            Help.pop();
        }
        Help.push(CurValue );
    }
    while (!Help.empty())//再把反序元素放回到原栈中
    {
        int Val = Help.top();
        InputStack.push(Val);
        Help.pop();
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值