1. 程式人生 > >棧、佇列系列

棧、佇列系列

 劍指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;
}