1. 程式人生 > >【程式設計師面試寶典】棧和佇列相關面試題

【程式設計師面試寶典】棧和佇列相關面試題

1、集合棧

題目描述:

請實現一種資料結構SetOfStacks,由多個棧組成,其中每個棧的大小為size,當前一個棧填滿時,新建一個棧。該資料結構應支援與普通棧相同的push和pop操作。

給定一個操作序列int[][2]ope(C++為vector<vector<int>>),每個操作的第一個數代表操作型別,若為1,則為push操作,後一個數為應push的數字;若為2,則為pop操作,後一個數無意義。請返回一個int[][](C++為vector<vector<int>>),為完成所有操作後的SetOfStacks,順序應為從下到上,預設初始的SetOfStacks為空。保證資料合法。

問題分析:

(1)首先建立一個存放長度達到size的棧vec,用來存放長度達到size的棧(vector<vector<int>>);

(2)在建立一個temp棧用來操作當前要進行操作的資料(vector<int>);

(3)進來之後for迴圈遍歷0~ope.size(),對於壓棧的情況ope[i][0]==1,先判斷棧temp棧中的元素是否達到size個,如果達到就將其先壓入vec棧中,再清空temp棧,執行temp的壓棧操作,否者直接將元素壓入到temp當中;

(4)對於出棧時,首先判斷temp棧是否為空,不為空則直接從temp中丟擲元素,否則讓temp指向vec棧的棧頂,然後讓vec和temp都執行元素出棧動作。

(5)最後如果temp中的元素個數不為空,則將temp壓入到vec當中,返回vec即可

程式碼實現

vector<vector<int> > setOfStacks(vector<vector<int> > ope, int size) {
	vector<vector<int> > stack;
	vector<int> temp;
	for (int i = 0; i<ope.size(); i++){
		if (ope[i][0] == 1){
			if (temp.size() == size){
				stack.push_back(temp);
				temp.clear();
				temp.push_back(ope[i][1]);
			}
			else
				temp.push_back(ope[i][1]);
		}
		if (ope[i][0] == 2){
			if (temp.size()>0){
				temp.pop_back();
			}
			else{
				temp = stack[stack.size() - 1];
				temp.pop_back();
				stack.pop_back();
			}

		}
	}
	if (temp.size() != 0)
		stack.push_back(temp);
	return stack;
}
2、兩個棧實現佇列

3、雙棧排序

題目描述:

請編寫一個程式,按升序對棧進行排序(即最大元素位於棧頂),要求最多隻能使用一個額外的棧存放臨時資料,但不得將元素複製到別的資料結構中。

給定一個int[]numbers(C++中為vector<int>),其中第一個元素為棧頂,請返回排序後的棧。請注意這是一個棧,意味著排序過程中你只能訪問到第一個元素。

測試樣例[1,2,3,4,5]返回:[5,4,3,2,1] 問題分析: (1)首先建立一個輔助棧temp,用來存放最終要返回的棧; (2)將numbers的第一個元素push到輔助棧中,其後的過程就和插入排序的思路完全一樣,只不過再此使用vector的介面來進行實現的; (3)因為要對棧進行升序排序,所以若numbers[i]<temp.back()(小於棧頂)時,直接將其插入到後面,否則就需要在temp中遍歷找合適的位置在插入。 (4)所有元素都操作完之後,返回最後排好序的temp棧即可 程式碼實現:
vector<int> twoStacksSort(vector<int> numbers) {
	vector<int> temp;
	int size = numbers.size();
	if (size <= 1)
		return numbers;
	temp.push_back(numbers[0]);
	for (int i = 1; i<size; ++i)
	{
		if (numbers[i] <= temp.back())
			temp.push_back(numbers[i]);
		else
		{
			vector<int>::iterator it;
			for (it = temp.begin(); it != temp.end(); ++it)
			{
				if (*it<numbers[i])
					break;
			}
			temp.insert(it, numbers[i]);
		}
	}
	return temp;
}
4、貓狗收容所 題目描述:

有家動物收容所只收留貓和狗,但有特殊的收養規則,收養人有兩種收養方式,第一種為直接收養所有動物中最早進入收容所的,第二種為選擇收養的動物型別(貓或狗),並收養該種動物中最早進入收容所的。

       給定一個操作序列int[][2]ope(C++中為vector<vector<int>>)代表所有事件。若第一個元素為1,則代表有動物進入收容所,第二個元素為動物的編號,正數代表狗,負數代表貓;若第一個元素為2,則代表有人收養動物,第二個元素若為0,則採取第一種收養方式,若為1,則指定收養狗,若為-1則指定收養貓。請按順序返回收養的序列。若出現不合法的操作,即沒有可以符合領養要求的動物,則將這次領養操作忽略。

測試樣例[[1,1],[1,-1],[2,0],[2,-1]]返回:[1,-1] 問題分析 (1)根據題目要求,這道題考查的是我們的邏輯思想,問題的描述已經十分清晰,相應的用程式碼實現出來即可; (2)首先建立兩個vector<int>的變數vec和arr,分別儲存進入收容所中的動物和被領養的動物; (3)接下來就是分情況,若ope[i][0]==1表示有動物進來,只需要不斷的將其push到arr中,否則說明有動物將要被領養,對於要被領養的動物有三種情況。 (4)在arr棧不為空時,ope[i][1]==0,只需依次從arr中push,並將push後的資料從arr中erase掉,對於ope[i][1]==1/-1的情況,方法是一樣的,需要遍歷arr然後找到我們需要的元素,將其push到vec中,然後從arr中在erase掉。 (5)最後所有元素都處理完,只需要返回處理完後的res即可。 程式碼實現:
vector<int> asylum(vector<vector<int> > ope)
{
	vector<int> res, arr;
	int size = ope.size();
	if (ope.empty())
		return arr;
	for (int i = 0; i < size; i++)
	{
		if (ope[i][0] == 1)
		{
			res.push_back(ope[i][1]);
		}
		else if (ope[i][0] == 2)
		{
			if (!arr.empty())
			{
				if (ope[i][1] == 0)
				{
					res.push_back(arr[0]);
					arr.erase(arr.begin());
				}
				else if (ope[i][1] == 1)
				{
					for (int j = 0; j < res.size(); j++)
					{
						if (arr[j]>0)
						{
							res.push_back(arr[j]);
							arr.erase(arr.begin() + j);
							break;
						}
					}
				}
				else if (ope[i][1] == 2)
				{
					for (int j = 0; j < res.size(); j++)
					{
						if (arr[j]>0)
						{
							res.push_back(arr[j]);
							arr.erase(arr.begin() + j);
							break;
						}
					}
				}
			}
		}
		return res;
	}
}