栈面试题总结
2016-08-23 11:13
141 查看
1.求栈上的最小值
具体要求:在O(1)的时间复杂度内求出栈上的最小值,并且不受出栈入栈的影响。思路:借助一个辅助栈,原栈在有数据入栈的时候,辅助栈也有数据入栈。辅助栈入栈的数据为当前的最小值。
实现:
template<typename T> class StackMin { public: void Push(const T&data); void Pop(); T Min(); private: stack<T>st1; stack<T>st2; }; template<typename T> void StackMin<T>::Push(const T&data) { st1.push(data); if (st2.size() == 0 || st2.top() > data) st2.push(data); else st2.push(st2.top()); } template<typename T> void StackMin<T>::Pop() { if (st1.size() == 0) return; st1.pop(); st2.pop(); } template<typename T> T StackMin<T>::Min() { return st2.top(); }
2.利用两个栈实现队列
具体要求:实现队列的push,pop,front,back操作思路:栈上的数据为先进后出,队列上的数据为先进先出。可以用栈1专门用来放push的数据,如果要pop的时候,就把栈1的数据存入到栈2中去,对栈2进行pop。
实现:
template<typename T> class QueueOfTwoStack { public: void Push(const T&data); void Pop(); T&Front()////可以合并 { if (st2.empty()) { while (!st1.empty()) { st2.push(st1.top()); st1.pop(); } } return st2.top(); } T&Back() { if (st1.empty()) { while (!st2.empty()) { st1.push(st2.top()); st2.pop(); } } return st1.top(); } private: stack<T>st1; stack<T>st2; }; template<typename T> void QueueOfTwoStack<T>::Push(const T&data) { st1.push(data); } template<typename T> void QueueOfTwoStack<T>::Pop() { if (st2.size() == 0) { int count = st1.size(); for (size_t i = 0; i < count; i++) { st2.push(st1.top()); st1.pop(); } st2.pop(); } else st2.pop(); }
3.利用两个队列实现栈
具体要求:实现栈的Push,pop,top操作思路:队列的数据是满足先进先出,栈上的数据满足先进后出。可以用一个队列来接收数据,当要出数据的时候,把前面的数据都放到另一个队列上去,留下最后一个。然后交换两个队列,进行下一波操作。
实现:
template<typename T> class StackWithTwoQueue { public: void Push(const T&data); void Pop(); T&Top() { assert(!qu1.empty()); return qu1.back(); } private: queue<T>qu1; queue<T>qu2; }; template<typename T> void StackWithTwoQueue<T>::Push(const T&data) { qu1.push(data); } template<typename T> void StackWithTwoQueue<T>::Pop() { if (0 == qu1.size()) return; int count = qu1.size(); for (int i = 0; i < count - 1; i++) { qu2.push(qu1.front()); qu1.pop(); } qu1.pop(); swap(qu1, qu2);//交换 }
4.数组判断是否为出栈顺序
具体要求:如果是对的顺序就返回true,否则返回false思路:借助一个栈来实现,将Push的值挨个入栈,同时进行判断栈顶的值是否与pop的第一个值相等,如果相同就出栈。最后如果栈为空,并且pop的也走到了最后,就说明是出栈顺序。
实现:
bool IsPopOrder(const int*pPush, const int*pPop, int length) { bool ret = false; if (NULL == pPush || NULL == pPop || length <= 0) return ret; const int*pNextPush = pPush; const int*pNextPop = pPop; stack<int>s; while (pNextPop - pPop < length) { while (s.size() == 0 || *pNextPop != s.top()) { if (pNextPush - pPush == length) break; s.push(*pNextPush); pNextPush++; } if (s.top() != *pNextPop) break; s.pop(); pNextPop++; } if (s.empty() && pNextPop - pPop == length) ret = true; return ret; }
5.背包问题
具体要求:背包的承重固定,从一系列物品中挑出刚好能放满背包的所有物品。
思路:借助一个栈来实现,栈中放的是物品数组的下标。依次往栈中放元素,如果超过了承重,就将其pop,放入一个元素来比较。
实现:
void backpack(int *arr, int size, int weight) { assert(arr); int begin = 0; int sum = 0; stack<int> s; int pos = 0; while (begin < size) { if (pos < size) { s.push(pos); sum += arr[pos]; if (sum == weight) { Print(arr, s); } if (sum > weight) { sum -= arr[s.top()]; s.pop(); } pos++; } else { sum -= arr[s.top()]; pos = s.top() + 1; s.pop(); } if (s.empty()) { begin++; pos = begin; sum = 0; } } }