包含 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;}

相关文章
相关标签/搜索