剑指offer——包含max函数的栈(30题)和队列(59题)

1、包含max函数的栈

思想很简单,在申请一个数据栈的同时也申请一个辅助栈。辅助栈用来存放数据栈中最大值与新压入栈元素两者间的较大值,也就是说辅助栈的栈顶元素永远都是数据栈元素的最大值。

实现代码如下:

#include<iostream>
#include<stack>
#include<assert.h>

using namespace std;

template<typename T>
class stackWithMax {
public:
	T max()const;
	void push(T val);
	void pop();
private:
	stack<T> mdata;//数据栈
	stack<T> m_max;//辅助栈
};

template<typename T>
void stackWithMax<T>::push(T val) {
	mdata.push(val);
	if (m_max.size() == 0 || val > m_max.top()) {//压入的数据栈元素与辅助栈栈顶元素比较大小
		m_max.push(val);
	}
	else
		m_max.push(m_max.top());
}

template<typename T>
void stackWithMax<T>::pop() {
	assert(mdata.size() >> 0 && m_min.size() > 0);

	mdata.pop();
	m_max.pop();
}
template<typename T>
T stackWithMax<T>::max()const {
	assert(mdata.size() >> 0 && m_min.size() > 0);
	return m_max.top();
}

2、包含max函数的队列

实现该队列,需要用到两个双端队列,一个用来存数据元素,另一个双端队列maximums用来存储最大值。

maximums存储原则:假设push元素值A,但凡A比maximums尾部值小时,直接压入maximums。若比maximums尾部值大时,先将maximums尾部元素弹出,循环直到A比尾部值小或maximums为空时,再压入A。

弹出数据元素时,针对maximums双端队列,判断队头元素(最大值)是否是弹出元素,若是,则同时也弹出maximums的队头元素,若不是,则不操作maximums队列。

实现代码如下:

#include<deque>
#include<iostream>
#include<assert.h>

using namespace std;

template<typename T>
class queueWithMax {
public:
	queueWithMax():currentIndex(0){}
	void push(T number);
	void pop();
	T max()const;
	T front()const;


private:
	struct InternalData {//此处引入一个数据结构,方便判断弹出元素是否是队列中的最大值。
		T number;
		int index;
	};
	deque<InternalData> data;
	deque<InternalData> maximums;
	int currentIndex;
};

template<typename T>
void queueWithMax<T>::push(T number) {
   //条件语句中若只采用>号,可以简化InternalData数据结构(即不需要引用下标值)
	while (!maximums.empty() && number >= maximums.back().number)
		maximums.pop_back();
	InternalData iData = { number,currentIndex };
	data.push_back(iData);
	maximums.push_back(iData);

	++currentIndex;
}

template<typename T>
void queueWithMax<T>::pop() {
	assert(!data.empty());
	
	if (data.front().index == maximums.front().index)
		maximums.pop_front();
	data.pop_front();
}

template<typename T>
T queueWithMax<T>::front() const{
	assert(!data.empty());
	return data.front().number;
}

template<typename T>
T queueWithMax<T>::max()const {
	assert(!data.empty());
	return maximums.front().number;
}

int main() {
	queueWithMax<int> q;
	q.push(12);
	q.push(4);
	q.push(17);
	q.push(7);
	q.push(100);
	q.push(88);
	cout << "The max value from queue is " << q.max() << endl;
	cout << "The first value from queue is " << q.front() << endl;
	q.pop();
	cout << "The second value from queue is " << q.front() << endl;

	return 0;
}

3、实现一个含min函数的栈和队列

思想与上述类似,不再给出代码。

再想一下,如果在栈或队列既实现max,又实现min。还是很简单,不过就是多开一个辅助栈或多申请一个双端队列罢了,代码也不再给出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值