主要思路:
1)建立两个栈_data与_mindata,其中_data作为数据栈,存放每一个入栈的数据;_mindata作为数据最小栈,存放数据栈中当前最小的数据;
2)当元素data入栈时,将data入栈到_data数据栈中,并让data与_data的栈顶元素做比较,如果x小于等于_data的栈顶元素,则将data入栈到_mindata最小数据栈中;
3)当元素出栈时,让_data与_mindata的栈顶元素做比较,如果栈顶元素相等,则将_data与_mindata的栈顶元素同时出栈,否则只让_data数据栈的栈顶元素出栈;
4)当求栈中最小元素时,直接让最小元素栈的栈顶元素出栈。
#include
#include
using namespace std;
typelate
class Minstack
{
public:
void push(const T &data)
{
_data.push(data);
if(_mindata.empty() || data <= _mindata.top())
{
_mindata.push(data);
}
}
void pop()
{
if(_data.empty())
{
return;
}
if(!_data.empty() && _data.top() == _mindata.top())
{
_mindata.pop();
}
_data.pop();
}
const T Min()
{
if(_mindata.empty())
{
return T();
}
return _mindata.top();
}
void Print()
{
while(!_data.empty())
{
cout<<_data.top()<<" ";
_data.pop();
}
cout< _data, _mindata;
};
思路: push 比较容易,直接把数据push 进stack1中
pop需要将stack1中的数据push进stack2中,这样栈1的先入后出就可以变成栈2的先入先出,将栈2中的顶部数据返回即为队列的pop数据
再将栈2中的数据push回去栈1,保持原始状态。
public class Solution
{
public:
Stack stack1 = new Stack();
Stack stack2 = new Stack();
//入栈给stack1
void push(int node)
{
stack1.push(node);
}
//pop
//出栈时,若stack2不为空,则出栈,
* 若为空,把stack1的内容全部放入stack2,然后出栈。
public int pop()
{
while(!stack2.isEmpty())
{
return stack2.pop();
}
while(!stack1.isEmpty())
{
return stack2.pop(stack1.pop);
}
return stack2.pop();
}
public static void main(String[] args)
{
}
};
思路:
1.先设计两个队列:一个用于入栈input,一个用于出栈output
2.当元素要入栈的时候,直接入栈input
3.当元素要出栈时,先判断output中是否有元素。若是有,可以直接将output中的栈顶元素出队列;若是没有,则先将input中的元素入到output中,再判断栈是否为空,若不为空,将output的元素除队尾元素外入到input中,再将output中的栈顶元素出队列;
4.判断队列是否为空,依次判断input与output是否为空,若有其中一个栈不为空,则队列就不为空;
5.求栈顶元素,首先判断栈是否为空,若不为空,将input中的元素入到output中,若output不为空,则打印output队尾元素;
6.求队列的大小,将队列input与output的大小相加即可。
#include
template
class Two_Queue_To_Stack
{
public:
//插入
void Push(const T& x)
{
input.push(x);
}
//删除
void Pop()
{
if(!output.empty())
{
output.pop();
}
else
{
while(!input.empty())
{
output.push(input.front());
input.pop();
}
if(!Empty())
{
while(output.size() - 1)
{
input.push(output.front());
output.pop();
}
output.pop();
}
else
{
cout<<"删除时发现该队列为空"< input;
queue output;
};
void TestTwo_Queue_To_Stack()
{
Two_Queue_To_Stack q;
q.Push(1);
q.Push(2);
q.Push(3);
q.Push(4);
q.Push(5);
//q.Printf();
q.Pop();
q.Pop();
q.Pop();
//q.Pop();
//q.Pop();
//q.Pop();
//q.Printf();
cout<<"Empty: "<
这道题我们可以创建两个栈(感觉有点类似两个栈实现一个队列),需要几个数字放在前面即把S1的栈顶元素取几个放在S2里面即可
出栈时候先判断S2是否为空,不为空则从S2栈顶元素逐个取出,再从S1中取出剩下的元素即可
#include
#include
#include
using namespace std;
typlate int T
class Stack
{
public:
Stack()
{}
~Stack()
{}
//push
void push(T data)
{
s1.push(data);
}
//pop
void pop()
{
while(!s2.empty())
{
cout<<"s2.pop"<<"s2.top"<<")"< s1.size() && x<0)
return ;
while(x)
{
T temp = s1.top();
if(!s1.empty())
{
s1.pop();
s2.push(temp);
}
--x;
}
}
private:
stack s1;
stack s2;
};
int main()
{
Stack s;
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Push(5);
s.NumReverse(2);
s.Pop();
s.Pop();
s.Pop();
s.Pop();
return 0;
}
方法:
下标为0的位置为栈1的栈底,栈2的栈底在下标最大的位置上。栈1向左扩展,栈2向后扩展。这种方法不会出现浪费内存的情况。
#define Max 10
#define DataType int
typedef struct SharedStack
{
DataType data[Max];
int top1;
int top2;
}sharedstack;
栈的初始化:
//共享栈初始化
void InitShared(sharedstack *s)
{
assert(s);
s->top1 = 0;
s->top2 = Max - 1;
memset(s->data, 0, Max*sizeof(DataType));
}
入栈:
//while == 1 表示栈1,d表示要入栈的数据
void PushSharedStack(sharedstack *s, DataType d, int which)
{
assert(s);
if(while == 1)
{
if(s->top1 <= s->top2)
{
s->data[s->top1++] = d;
}
else
{
printf("栈满\n");
return;
}
}
else
{
if(s->top1 <= s->top2)
{
s->data[s->top2--] = d;
}
else
{
printf("栈满\n");
return;
}
}
}
出栈:
void PopSharedStack(sharedstack *s, int which)
{
assert(s);
if(while == 1)
{
if(s->top1 != 0)
{
s->top1--;
}
else
{
printf("栈空\n");
return ;
}
}
else
{
if(s->top2 != 0)
{
s->top2++;
}
else
{
printf("栈空\n");
return;
}
}
}
栈顶元素:
DataType SharedStackTop(sharedstack *s, int which)
{
assert(s);
if(while == 1)
{
if(s->top1 == 0)
{
printf("栈空\n");
return -1;
}
else
{
return s->data[s->top1-1];
}
}
else
{
if(s->top2 == 0)
{
printf("栈空\n");
return -1;
}
else
{
return s->data[s->top2+1];
}
}
}
栈长短:
//栈长短
DataType SharedStackSize(sharedstack *s, int which)
{
assert(s);
if (which == 1)
{
return s->top1;
}
else
return Max - s->top2 - 1;
}
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。
/*时间复杂度o(n),空间复杂度为o(n)
思路就是采用双端队列,队列中的头节点保存的数据比后面的要大。
比如当前假如的数据比队尾的数字大,说明当前这个数字最起码在从现在起到后面的过程中可能是最大值
,而之前队尾的数字不可能最大了,所以要删除队尾元素。
此外,还要判断队头的元素是否超过size长度,由于存储的是下标,所以可以计算得到;
特别说明,我们在双端队列中保存的数字是传入的向量的下标;
*/
class Solution {
public:
vector maxInWindows(const vector& num, unsigned int size)
{
vector vec;
if(num.size()<=0 || num.size() dq;
//处理前size个数据,因为这个时候不需要输出最大值;
for(unsigned int i=0;i=num[dq.back()])
dq.pop_back();//弹出比当前小的元素下标
dq.push_back(i);//队尾压入当前下标
}
//处理size往后的元素,这时候需要输出滑动窗口的最大值
for(unsigned int i=size;i=num[dq.back()])
dq.pop_back();
if(!dq.empty() && dq.front()<=(int)(i-size))//判断队头的下标是否超出size大小,如果超过,要删除队头元素
dq.pop_front();//删除队头元素
dq.push_back(i);//将当前下标压入队尾,因为可能在未来是最大值
}
vec.push_back(num[dq.front()]);//最后还要压入一次
return vec;
}
};