1、实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最
小值的操作)的时间复杂度为O(1)
针对这个问题我们可以有两种方法来解决,第一种方法:
我们每次压栈的时候压两个数字,先压数据,然后压最小值,每次压之前和数据比较一下,如果数据比最小值还小就把最小值更新成数据,然后再压数据和最小值,这就是压栈操作。这样可以保证栈顶就是最小值。
接下来是出栈操作,因为我们每次多压了一个数据所以出栈的时候要多出一个,每次弹出两个数据,一个是最小值,一个是原数据。
最小值每次只要取最小值就可以了。
第二种方式:
我们使用一个辅助栈,压栈的时候,刚开始两个栈都空的的情况下,两个栈同时压栈操作,接下来每次压栈,先判断插入的数据是否比第二个栈的栈顶小,小得话两个栈同时压栈,否则只对第一个栈进行压栈,直到所有数据都被插入。
使用两个栈实现一个队列
入队列时,我们直接对栈1进行压栈操作就可以了,
出队列时,如果栈1不为空栈2为空,就把栈1所有元素都出栈,都压入栈2中,每次出队列,对栈2执行出栈操作,直到栈2元素全部弹出,然后再执行前面的操作。
使用两个队列实现一个栈
入栈时先看队列1是不是空,队列1不为空直接入队列,如果为空队列2入队列,
出栈时,如果队列1为空,就把队列2除过最后一个以外的所有元素,都入到第一个队列,然后把队列2剩下的最后一个元素弹出,如果队列1不为空就把队列1除过最后一个元素其他元素都入第二个队列,然后弹出队列1最后一个元素,总之,出栈操作就是把队列只剩要出栈的元素其他全部搬移,然后再将这个元素出队列即可
元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出
栈序列为(4,5,3,2,1)
要验证出栈顺序的合法性,还是的通过一个栈来验证,我们用一个函数来验证,函数总共四个参数,一个数组用来保存入栈序列,另一个数组用来保存待验证的出栈序列,另外两个参数是这两个序列的大小,首先我们直到出栈入栈元素个数肯定是不变的,所以一进入函数先判断两个序列的大小是否相等,如果连大小都不相等就不用进行下面操作了,直接返回就好了,如何相等的话再进行下面的操作,定义一个循环对入栈序列进行入栈操作,还要设置一个内循环,当栈顶元素和出栈序列元素相同时栈执行出栈操作,输出序列向后走,如果不满组循环条件就一直入栈。如果出栈序列是合法的那么入栈的元素也会都被弹出所以,栈就是空的,所以最后再判断一下,栈是否为空,为空的话表示,出栈序列是合法的,否则就是不合法的。
一个数组实现两个栈(共享栈)
我们这里栈的实现是两个栈的栈底在数组的两端,当两个栈的大小之和大于等于总容量的时候,将执行扩容操作,将整片空间扩大至原来的两倍,然后将两个栈的元素都搬到新的空间中,出栈的时候改变当前位置即可。
代码以及测试用例如下:
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
//实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最
//小值的操作)的时间复杂度为O(1)
//方法一
class Stack1
{
public:
void Push(int data)
{
if (_s.empty())
{
_min = data;
}
else
{
if (data < _min)
_min = data;
}
_s.push(data);
_s.push(_min);
}
void Pop()
{
if (_s.empty())
return;
_s.pop();
_s.pop();
}
int Min()
{
if (_s.empty())
return -1;
return _s.top();
}
private:
stack<int> _s;
int _min;
};
class Stack2
{
public:
void Push(int data)
{
_s1.push(data);
if (_s2.empty() || data < _s2.top())
_s2.push(data);
}
void Pop()
{
if (_s1.empty() && _s2.empty())
return;
if (_s1.top() == _s2.top())
{
_s2.pop();
}
_s1.pop();
}
int Min()
{
if (_s1.empty())
return -1;
return _s2.top();
}
private:
stack<int> _s1;
stack<int> _s2;
};
//使用两个栈实现一个队列
class Queue
{
public:
void Push(int data)
{
_s1.push(data);
cout << "top" << _s1.top() << endl;
}
void Pop()
{
if (!_s2.empty())
_s2.pop();
else
{
while (!_s1.empty())
{
int tmp = _s1.top();
cout <<"pop"<< tmp << " ";
_s1.pop();
_s2.push(tmp);
}
cout << "Top" << _s2.top() << endl;
}
}
private:
stack<int> _s1;
stack<int> _s2;
};
//使用两个队列实现一个栈
class Stack
{
public:
void Push(int data)
{
if (!_q1.empty())
_q1.push(data);
else
_q2.push(data);
}
void Pop()
{
if (_q1.empty())
{
while (_q2.size() > 1)
{
int tmp = _q2.front();
_q2.pop();
_q1.push(tmp);
}
_q2.pop();
}
else
{
while (_q1.size() > 1)
{
int tmp = _q1.front();
_q1.pop();
_q2.push(tmp);
}
_q1.pop();
}
}
private:
queue<int> _q1;
queue<int> _q2;
};
//元素出栈、入栈顺序的合法性。如入栈的序列(1, 2, 3, 4, 5),出
//栈序列为(4, 5, 3, 2, 1)
bool Legal(int input[], int output[],int in_len,int out_len)
{
if (in_len != out_len)
return false;
stack<int> s;
int i = 0;
int j = 0;
for (; i < in_len; i++)
{
s.push(input[i]);
while (s.size()>0 && s.top() == output[j])
{
s.pop();
j++;
}
}
return (s.size() > 0 ? false : true);
}
//一个数组实现两个栈(共享栈)
class ShareStack
{
public:
ShareStack()
:_array(new int[2]),
_size1(0),
_size2(1),
_capacity(2)
{}
~ShareStack()
{
if (_array != NULL)
{
delete[] _array;
_array = NULL;
_size1 = 0;
_size2 = 0;
_capacity = 0;
}
}
void Push1(const int& data)
{
Capacity();
_array[_size1] = data;
_size1++;
}
void Push2(const int& data)
{
Capacity();
_array[_size2] = data;
_size2--;
}
void Pop1()
{
if (_size1 > 0)
{
_size1--;
}
}
void Pop2()
{
if (_size2 != _capacity - 1)
_size2++;
}
int Size1()
{
return _size1;
}
int Size2()
{
return _capacity - 1 - _size2;
}
int Top1()
{
return _array[_size1-1];
}
int Top2()
{
return _array[_size2+1];
}
bool Empty1()
{
return _size1 == 0;
}
bool Empty2()
{
return _size2 == _capacity - 1;
}
void Display1()
{
if (_size1 > 0)
{
for (int i = _size1 - 1; i >= 0; i--)
{
cout << _array[i] << " ";
}
cout << endl;
}
}
void Display2()
{
if (_size2 > 0)
{
for (int i = _size2+1; i < _capacity; i++)
{
cout << _array[i] << " ";
}
cout << endl;
}
}
private:
void Capacity()
{
if ((Size1() + Size2()) >= _capacity)
{
int newcapacity = _capacity * 2;
int * tmp = new int[newcapacity];
int k = newcapacity - 1;
for (int i = 0; i < _size1; i++)
{
tmp[i] = _array[i];
}
for (int i = _capacity - 1; i>_capacity - _size2; i--)
{
tmp[k] = _array[i];
k--;
}
delete[] _array;
_size2 = newcapacity - (_capacity - _size2);
_capacity = newcapacity;
_array = tmp;
}
}
int *_array;
int _size1;
int _size2;
int _capacity;
};
void Test1()
{
Stack1 s;
s.Push(3);
s.Push(6);
s.Push(4);
s.Push(2);
s.Push(5);
cout << s.Min() << endl;
s.Pop();
s.Pop();
cout << s.Min() << endl;
}
void Test2()
{
Stack2 s;
s.Push(3);
s.Push(6);
s.Push(4);
s.Push(2);
s.Push(5);
cout << s.Min() << endl;
s.Pop();
s.Pop();
cout << s.Min() << endl;
}
void Test3()
{
Queue q;
q.Push(2);
q.Push(6);
q.Push(1);
q.Push(3);
q.Push(5);
q.Pop();
}
void Test4()
{
Stack s;
s.Push(2);
s.Push(6);
s.Push(1);
s.Pop();
s.Push(3);
s.Push(5);
s.Pop();
}
void Test5()
{
int input[] = { 1, 2, 3, 4, 5 };
int output1[] = { 4, 5, 3, 2, 1 };
int output2[] = { 4, 5, 3, 1, 2 };
int in_len = sizeof(input) / sizeof(input[0]);
int out_len1 = sizeof(output1) / sizeof(output1[0]);
int out_len2 = sizeof(output2) / sizeof(output2[0]);
if (Legal(input, output1, in_len, out_len1))
cout << "合法\n" << endl;
else
cout << "不合法\n" << endl;
if (Legal(input, output2, in_len, out_len2))
cout << "合法\n" << endl;
else
cout << "不合法\n" << endl;
}
void Test6()
{
ShareStack s;
s.Push1(1);
s.Push1(2);
s.Push1(3);
s.Push1(4);
s.Push1(5);
s.Push1(6);
s.Push1(7);
s.Display1();
s.Pop1();
s.Display1();
cout << "Stack1 Top:" << s.Top1() << endl;
cout << "Stack1 Size:" << s.Size1() << endl;
cout << endl;
s.Push2(7);
s.Push2(8);
s.Push2(9);
s.Push2(10);
s.Display2();
s.Pop2();
s.Display2();
cout << "Stack2 Top:" << s.Top2() << endl;
cout << "Stack2 Size:" << s.Size2() << endl;
}
int main()
{
//Test1();
//Test2();
//Test3();
//Test4();
//Test5();
Test6();
}