1.实现一个栈,包括push、pop、取顶、size、打印等操作
2.实现一个队列,包括push、pop、取顶、size、打印等操作
只用一个数组实现三个栈
设计一个栈,支持pop、push、min操作,且这些操作的时间复杂需为O(1)
额外设计一个辅助栈,用来记录主栈当前状态的最小值
template<typename T>
class StackSuppliedMin{
public:
vector<T> datas;
vector<size_t> minStack;
void push(T data){
datas.push_back(data);
if (minStack.empty() || data < datas[minStack.back()])//min栈有元素入栈的情况
minStack.push_back(datas.size()-1);
}
void pop(){
assert(!datas.empty());
if (datas.back() == datas[minStack.back()]) //min栈元素出栈的情况
minStack.pop_back();
datas.pop_back();
}
T min(){
assert(!datas.empty() && !minStack.empty());
return datas[minStack.back()];
}
void display();
};
实现数据结构SetofStack,由多个栈组成,当一个栈满时新建一个栈,pop、push操作与普通栈相同,并且实现popAt(int index),指定子栈执行pop
以队列来实现栈
实现MyQueue类,以两个栈来实现一个队列
支持队列的add、poll、peek操作
Stackpush栈来接收数据、Stackpop来弹出数据,将Stackpush栈中的数据一次性导入Stackpop栈中。如果Stackpop栈中不为空,则不能够导入数据
使用一个额外的栈,对栈升序排列,支持push,pop,isEmpty操作
输入两个整数序列,第一个序列表示栈的压入序列,判断第二个序列是否为栈的弹出序列,假设压入该栈的所有数字都不相等
实现一个栈的逆序,但只能递归函数和这个栈的本身来实现,而不能使用额外的数据结构
一个栈中的元素为整型,将该栈的元素从底到顶从小到大排列,只允许使用一个额外的栈,不允许使用其他的数据结构
滑动窗口问题
问题解释有一个整型数组arr和一个大小为w的窗口,从数组的最左边滑动到最右边,窗口每次向右滑一个位置,返回一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值。以数组为[4,3,5,4,3,3,6,7],w =3为例,因为第一个窗口[4,3,5]的最大值为5,第二个窗口[3,5,4]的最大值为5,。。。所以最后返回[5,5,5,4,6,7]
方法一:普通解法
时间复杂度:O(N*w)
方法二利用双端队列:
时间复杂度:O(N)
生成双端队列qMAx;
while(i <= n){
if(qMax == NULL)
qMax.push_back(i);
else{
j=qMax.end();
if(arr[j]>arr[i])
qMax.push_back(i);
}
else{
while(arr[j]<=arr[i]){
qMax.pop_back();
j = qMax.end();
}
qMax.push_back(i);
}
//弹出规则
if(qMax.front == i-w){
qMax.pop_front();
}
if(i>= 2){
res.push_back(arr[qMax.front()])
}
}
给定一个没有重复元素的数组arr,写出生成这个数组的MaxTree函数,要求如果数组的长度为N,则时间复杂度为O(N)、额外空间复杂度为O(N)。
MaxTree的概念如下:
- MaxTree是一棵二叉树,数组中的每一位对应一个二叉树节点
- 包含MaxTree树在内且其中的每一棵子树上,最大值的节点都是树的头。
思路:每一个元素的父节点是左边第一个比它大的数和右边第一个比它大的数中较小的一个,如果这个元素是整个数组的最大节点,则它是MaxTree的头结点
利用栈得到每个数的左右两边第一个比它大的数