棧、佇列系列
劍指Offer(9)--用兩個棧實現佇列(用兩個佇列實現棧)
思路:
當需要輸出的時候,如果pop棧中有資料就直接輸出棧頂元素,如果沒有的話,將push棧中的資料全部倒入pop,然後將pop棧頂的資料輸出。
class TwoStacksQueue { public: void push(int obj); int poll(); int peek(); private: stack<int> stackPush; stack<int> stackPop; }; void TwoStacksQueue::push(int obj) { stackPush.push(obj); } int TwoStacksQueue::poll() { if (stackPush.empty() && stackPop.empty()) return -1; if (stackPop.empty()) { while (!stackPush.empty()) { stackPop.push(stackPush.top()); stackPush.pop(); } } int temp = stackPop.top(); stackPop.pop(); return temp; } //看一下,並不需要取走 int TwoStacksQueue::peek() { if (stackPush.empty() && stackPop.empty()) return -1; if (stackPop.empty()) { while (!stackPush.empty()) { stackPop.push(stackPush.top()); stackPush.pop(); } } int temp = stackPop.top(); return temp; }
兩個佇列實現棧
#include<iostream> #include<queue> using namespace std; //如何僅用佇列結構實現棧結構 class TwoQueuesStack { public: void push(int obj); int pop(); int peek(); private: queue<int> que; queue<int> help; }; void TwoQueuesStack::push(int obj) { que.push(obj); } int TwoQueuesStack::pop() { if (que.empty()) return -1; while (que.size() != 1) { help.push(que.front()); que.pop(); } int temp = que.front(); que.pop(); que.swap(help); return temp; }
劍指Offer(30)--包含min函式的棧
定義棧的資料結構,請在該型別中實現一個能夠得到棧的最下元素的min函式。在該棧中,呼叫min、push及pop的時間複雜度都為O(1)
思路:
準備兩個棧,一個用於正常放置元素的棧data,另一個min棧存放當前最小元素,在壓棧的過程中min棧隨著data棧增長,壓入
data棧的元素和min棧的棧頂比較,如果待壓入的數比min棧的棧頂要小,那麼min棧中也壓這個數;否則,重複壓入min棧的棧頂
彈出的時候,同步彈出即可
class MyStack { public: void push(int obj); int pop(); int getmin(); private: stack<int> stackMin; stack<int> stackData; }; void MyStack::push(int obj) { if (stackMin.empty() || obj < getmin()) stackMin.push(obj); else { int min = stackMin.top(); stackMin.push(min); } stackData.push(obj); } int MyStack::pop() { if (stackData.empty()) return -1; stackMin.pop(); int temp = stackData.top(); stackData.pop(); return temp; } int MyStack::getmin() { if (stackMin.empty()) return -1; return stackMin.top(); }
劍指Offer(31)--棧的壓入、彈出序列
輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否為該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。
思路:
建立一個輔助棧s,把輸入的第一個序列中的數字依次壓入該輔助棧,並按照第二個序列的順序依次從該棧中彈出數字。
判斷第二個序列待輸出的數字是否是棧頂元素,如果不是,則從輸入序列中依次輸入棧中,如果一直沒找到,則返回為false。
#include<iostream>
#include<stack>
using namespace std;
bool IsPopOrder(const int* Push, const int *Pop, int length)
{
if (Push == nullptr || Pop == nullptr || length < 1)
return false;
const int* nextPush = Push;
const int* nextPop = Pop;
stack<int> sData;
//只要彈出序列不為空,一直迴圈
while (nextPop - Pop < length)
{
while (sData.empty() || sData.top()!=*nextPop)
{
//輸入序列中沒有元素了
if (nextPush - Push == length)
break;
sData.push(*nextPush);
++nextPush;
}
if (sData.top() != *nextPop)
break;
sData.pop();
++nextPop;
}
if (sData.empty() && nextPop - Pop == length)
return true;
return false;
}
劍指Offer(59)--佇列的最大值
給定一個數組和滑動視窗的大小,找出所有滑動窗口裡數值的最大值。例如,如果輸入陣列{2,3,4,2,6,2,5,1}及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為{4,4,6,6,6,5}; 針對陣列{2,3,4,2,6,2,5,1}的滑動視窗有以下6個: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
vector<int> MaxInWindow(const vector<int>& num, int size)
{
vector<int> maxInwindows;
if (num.size() >= size && size >= 1)
{
//連結串列頭部存放當前的最大值
deque<int> index;
for (int i = 0; i < size; ++i)
{
while (!index.empty() && num[i] >= num[index.back()])
index.pop_back();
index.push_back(i);
}
for (int i = size; i < num.size(); ++i)
{
//存放視窗的最大值
maxInwindows.push_back[num[index.front()]];
while (!index.empty() && num[i] >= num[index.back()])
index.pop_back();
if (!index.empty() && index.front() <= (i - size))
index.pop_front();
//不論大小都會先存入連結串列中,因為有可能是後面值中的最大值
index.push_back(i);
}
maxInwindows.push_back(num[index.front()]);
}
return maxInwindows;
}