包含 min 函數的棧,棧的壓入、彈出序列

題目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;}

相關文章
相關標籤/搜索