題目1:定義棧的數據結構,請在該類型中實現一個可以獲得棧的最小元素的 min 函數。在該棧中,調用 min,push, pop 的時間複雜度都是 O(1)。ios
看到這一問題的第一反應是: 每次壓入一個新元素時,將棧裏的全部元素進行排序,讓最小的元素位於棧頂,這樣就能在 O(1) 的時間內獲得棧中的最小元素了。但這種思路不能保證最後壓入棧的元素就可以先出棧,破壞了棧的數據結構。數據結構
接着能夠想到在棧裏添加一個成員變量存放最小元素。每次壓入新元素的時候,若是該元素比當前最小元素還要小,則更新最小元素。然而當最小元素出棧後,咱們沒法獲得次小元素。函數
咱們能夠把每次的最小元素(以前的最小元素和新壓入棧的元素二者的較小者)都保存起來放到一個輔助棧中。以下表所示:spa
從上表中能夠看出,若是每次把最小元素壓入到輔助棧中,那麼就可以保證輔助棧頂的元素一直都是最小元素。當最小元素從數據棧中出棧的以後,同時彈出輔助棧的棧頂元素,此時,輔助棧的棧頂元素就是下一個最小值。排序
//包含Min 函數的棧
#include<iostream>
#include<stack>
using namespace std;io
const int MaxSize = 10;
template <typename T>
class Stack
{
public:
Stack(){}
~Stack(){}class
const T& minValue();
void push(const T& value);
void pop();stream
private:
stack<T> m_data; //數據棧
stack<T> m_min; //輔助棧
};變量
template<typename T>
void Stack<T>::push(const T& value)
{
m_data.push(value);
if(m_min.size() == 0 || value < m_min.top())
m_min.push(value);
else
m_min.push(m_min.top());
}im
template<typename T>
void Stack<T>::pop()
{
if(m_data.size() > 0 && m_min.size() > 0)
{
m_data.pop();
m_min.pop();
}
else
return;
}
template<typename T>
const T& Stack<T>::minValue()
{
if(m_data.size() > 0 && m_min.size() > 0)
return m_min.top();
else
return -1;
}
int main()
{
Stack<int> s1;
s1.push(3);
s1.push(4);
s1.push(2);
s1.push(5);
cout << s1.minValue() << endl;
s1.pop();
s1.pop();
cout << s1.minValue() << endl;
system("pause");
return 0;
}
題目 2: 輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的數字均不相等。例如序列 1 2 3 4 5 是某棧的壓棧序列,序列 4 5 3 2 1 是該壓棧序列的一個彈出序列,可是 4 3 5 1 2 就不多是該壓棧序列的彈出序列。
根據出棧,入棧的過程,能夠找到判斷一個序列是否是棧的彈出序列的規律:若是下一個彈出的數字恰好是棧頂元素,那麼直接彈出;若是下一個彈出的數字不在棧頂,咱們把壓棧序列中尚未入棧的元素壓入輔助棧中,直到把下一個須要彈出的數字壓入棧頂爲止。若是全部的數字都壓入了棧仍然沒有找到下一個彈出的數字,那麼該序列不多是一個彈出序列。
// 輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。
#include<iostream>
#include<stack>
using namespace std;
bool IsPopOrder(int *pPush, int *pPop, int length)
{
bool bPossible = false;
if(pPush != NULL && pPop != NULL && length > 0)
{
const int *pNextPush = pPush;
const int *pNextPop = pPop;
stack<int> stackData;
while(pNextPop - pPop < length)
{
while(stackData.empty() || stackData.top() != *pNextPop)
{
if(pNextPop - pPop == length - 1)
break;
stackData.push(*pNextPush);
pNextPush ++;
}
if(stackData.top() != *pNextPop)
break;
stackData.pop();
pNextPop++;
}
if(stackData.empty() && pNextPop - pPop == length )
bPossible = true;
}
return bPossible;
}
int main()
{
int pPush[5] = {1, 2, 3, 4, 5};
int pPop1[5] = {4, 5, 3, 2, 1};
int pPop2[5] = {4, 5, 3, 1, 2};
cout << IsPopOrder(pPush, pPop1, 5) << endl;
cout << IsPopOrder(pPush, pPop2, 5) << endl;
system("pause"); return 0;}