问题:
假设有这样一个拥有3个操作的队列:
1. EnQueue(v): 将v加入队列中
2. DeQueue(): 使队列中的队首元素删除并返回此元素
3. MaxElement: 返回队列中的最大元素
设计一种数据结构和算法,让MaxElement操作的时间复杂度尽可能地低。
#include<iostream> #include<limits.h> using namespace std; class Stack { public: Stack() { stackTop = -1; maxStackItemIndex = -1; } void Push(int x) { if(stackTop >= MAXN - 1)return; stackItem[++stackTop] = x; if(x > Max()) { link2NextMaxIten[stackTop] = maxStackItemIndex;//保存下一个最大值的位置 maxStackItemIndex = stackTop;//保存当前最大值 } else link2NextMaxIten[stackTop] = -1; } int Pop() { if(stackTop >= 0) { int value = stackItem[stackTop]; if(stackTop == maxStackItemIndex)maxStackItemIndex = link2NextMaxIten[stackTop];//改变当前最大值 --stackTop; return value; } } bool Empty() { return stackTop == -1; } int Max() { if(maxStackItemIndex >= 0)return stackItem[maxStackItemIndex]; else return INT_MIN; } private: const static int MAXN = 100; int stackTop; int maxStackItemIndex; int stackItem[MAXN]; int link2NextMaxIten[MAXN]; }; class Queue { public: void EnQueue(int v) { stk2.Push(v); } int DeQueue() { if(stk1.Empty()) { while(!stk2.Empty()) { stk1.Push(stk2.Pop()); } } return stk1.Pop(); } int MaxElement() { return max(stk1.Max(),stk2.Max()); } private: Stack stk1; Stack stk2; };
题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
分析:我们需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候,同时pop辅助栈。具体代码如下
template<class T> class Stack { public: void push(const T& value) { value_stk.push(value); if(!min_stk.empty()) { if(value < min_stk.top())min_stk.push(value); else min_stk.push(min_stk.top()); } else min_stk.push(value); } void pop() { value_stk.pop(); min_stk.pop(); } T min()const { assert(!value_stk.empty() && !min_stk.empty()); return min_stk.top(); } private: stack<T> value_stk;//存放数据的栈 stack<T> min_stk;//存放最小值的栈 };
两个队列实现一个堆栈:
思路:整个过程中保持一个队列有数据,一个队列为空。push的时候往有数据的一个对列中加入,pop的时候,把有数据的队列除最后一个元素以外的push到另一个空队列中,最后一个元素删除,用inputQueue和outputQueue指针分别指向这两个队列
template <class T> class Stack { public: bool empty() { return q1.size() == 0 && q2.size() == 0; } void push(const T& value) { queue<T>* inputQueue = &q1; if(q1.size() == 0)inputQueue = &q2; inputQueue -> push(value); } T top() { queue<T>* inputQueue,*outputQueue; if(q1.size() == 0) { inputQueue = &q2; outputQueue = &q1; } else { inputQueue = &q1; outputQueue = &q2; } assert(inputQueue->size() > 0); while(inputQueue->size() > 1) { outputQueue->push(inputQueue->front()); inputQueue->pop(); } T value = inputQueue->front(); outputQueue->push(inputQueue->front()); inputQueue->pop(); return value; } void pop() { queue<T>* inputQueue,*outputQueue;//inputQueue指向有数据的队列,outputQueue指向空队列 if(q1.size() == 0) { inputQueue = &q2; outputQueue = &q1; } else { inputQueue = &q1; outputQueue = &q2; } assert(inputQueue->size() > 0); while(inputQueue->size() > 1) { outputQueue->push(inputQueue->front()); inputQueue->pop(); } inputQueue->pop(); } private: queue<T> q1;//两个工作队列,同一时间只有一个有数据 queue<T> q2; };
编程之美之队列中取最大值操作
时间: 2024-12-28 06:09:52