刷题:栈的相关操作
刷題:棧的相關(guān)操作
- 1. 設(shè)計(jì)一個(gè)具有g(shù)etMin功能的棧
- 2. 用一個(gè)棧實(shí)現(xiàn)另一棧的排序
- 3.Next Greater Node In Linked List
1. 設(shè)計(jì)一個(gè)具有g(shù)etMin功能的棧
要求:pop、push、getMin等函數(shù)的功能的時(shí)間復(fù)雜度都是O(1)。
思路:用兩個(gè)標(biāo)準(zhǔn)棧來實(shí)現(xiàn)。其中一個(gè)棧用于存儲(chǔ)數(shù)據(jù)(稱為數(shù)據(jù)棧,stackData),另一個(gè)棧用于存儲(chǔ)當(dāng)前數(shù)據(jù)棧中的最小值(稱為最小棧,stackMin)。
入棧規(guī)則:
假設(shè)入棧的數(shù)據(jù)為 num,則將其壓入stackData中,然后判斷stackMin是否為空。
- 如果stackMin 為空,則將num 也壓入stackMin中。
- 如果stackMin 不為空,則比較 num 與 stackMin 棧頂元素的大小。
- 如果num 小于等于 stackMin 棧頂元素,則將num 壓入stackMin中。
- 如果num 大于 stackMin 棧頂元素,則stackMin不做操作。
出棧規(guī)則:
將stackData的棧頂元素出棧,如該元素等于stackMin的棧頂元素,則stackMin將棧頂元素出棧。如該元素大于stackMin的棧頂元素,則stackMin不做操作。
獲取棧中最小元素時(shí),只需要輸出stackMin的棧頂元素。
具體代碼為:
class New_stack
{
public:New_stack();~New_stack();void push(int n);void pop();int top();int getMin();private:stack<int> stack_data;stack<int> stack_min;
};New_stack::New_stack()
{
}New_stack::~New_stack()
{
}void New_stack::push(int n)
{stack_data.push(n);if (stack_min.empty())stack_min.push(n);else if (n <= stack_min.top())stack_min.push(n);}
int New_stack::top()
{return stack_data.top();
}
void New_stack::pop()
{if (stack_data.empty())cout << "The stack is empty !" << endl;if (stack_data.top() == stack_min.top())stack_min.pop();stack_data.pop();
}
int New_stack::getMin()
{if (stack_data.empty())cout << "The stack is empty !" << endl;return stack_min.top();
}
測(cè)試代碼:
int main()
{cout <<"the stack who has getMin functon " << endl;New_stack stack_min;stack_min.push(10);stack_min.push(12);stack_min.push(5);stack_min.push(3);stack_min.push(54);for (int i = 0; i < 5; ++i){cout << "the stack min value: " << stack_min.getMin() << endl;stack_min.pop();}return 0;
}
測(cè)試結(jié)果:
2. 用一個(gè)棧實(shí)現(xiàn)另一棧的排序
要求:一個(gè)棧中的元素為整型,現(xiàn)在將棧從頂?shù)降装磸拇蟮叫〉捻樞蚺判颉V辉试S申請(qǐng)一個(gè)棧。除此之外,可以申請(qǐng)新的變量,但是不允許使用其他的數(shù)據(jù)結(jié)構(gòu)。
思路:申請(qǐng)一個(gè)棧用于存儲(chǔ)臨時(shí)的排序結(jié)果(記為temp_stack),申請(qǐng)一個(gè)變量用于記錄排序棧的棧頂元素(記為cur)。如果temp_stack為空,則將cur壓人temp_stack中;如果temp_stack不為空且cur 小于等于temp_stack的棧頂元素,則將壓入temp_stack中;如果temp_stack不為空且cur 大于temp_stack的棧頂元素,則需要將temp_stack棧中的元素壓入排序棧中,直到cur值小于等于temp_stack的元素或temp_stack為空。用這種方式排序后,temp_stack棧從頂?shù)降椎脑仨樞驗(yàn)閺男〉酱蟮捻樞颉R虼?#xff0c;還需要將temp_stack棧中的元素壓入原始棧中。從而實(shí)現(xiàn)棧從頂?shù)降装磸拇蟮叫〉捻樞蚺判颉?/p>
代碼:
void sortStackbyStack(stack<int> &s)
{stack<int> temp_stack;int cur = 0;while (!s.empty()){cur = s.top();s.pop();while (!temp_stack.empty() && temp_stack.top() < cur){s.push(temp_stack.top());temp_stack.pop();}temp_stack.push(cur);}while (!temp_stack.empty()){s.push(temp_stack.top());temp_stack.pop();}
}
測(cè)試代碼:
int main()
{stack<int> s;cout << endl <<"用棧將另一個(gè)棧排序: " << endl;cout <<" 原始棧: " ;s.push(1); s.push(5); s.push(6); s.push(4); s.push(7);for (int i = 0; i < 5; ++i){cout << s.top() << " ";s.pop();}cout << endl;cout << " 排序棧: ";s.push(1); s.push(5); s.push(6); s.push(4); s.push(7);sortStackbyStack(s);for (int i = 0; i < 5; ++i){cout << s.top() << " ";s.pop();}cout << endl;return 0;
}
測(cè)試結(jié)果:
3.Next Greater Node In Linked List
Leetcode1019題
該題是查找鏈表中當(dāng)前元素后面第一個(gè)大于當(dāng)前元素值的元素。用暴力法解決該問題時(shí)間復(fù)雜度是O(n^2)。但是這種做法肯定難以讓人滿意。所以需要尋找一種更好的方法。
該問題的最優(yōu)解是用棧來處理。具體思路為:
棧內(nèi)存放的是 結(jié)點(diǎn)的編號(hào)。 每壓入一個(gè)編號(hào)前,先檢查該編號(hào)對(duì)應(yīng)元素是否大于棧頂?shù)木幪?hào)對(duì)應(yīng)元素,、如果大于,則棧頂編號(hào)出列,且棧頂編號(hào)對(duì)應(yīng)元素的greater為 當(dāng)前編號(hào)對(duì)應(yīng)元素。如果不大于,則繼續(xù)壓棧。
這樣做的目的是 用棧來記錄哪些節(jié)點(diǎn)未找到它的目標(biāo)節(jié)點(diǎn)。沒找到目標(biāo)節(jié)點(diǎn)的節(jié)點(diǎn)就保留在棧中,那些找到目標(biāo)節(jié)點(diǎn)的節(jié)點(diǎn)則記錄它的目標(biāo)節(jié)點(diǎn)然后出棧。
具體代碼為:
vector<int> nextLargerNodes(ListNode* head) {stack<int> hole;vector<int> values;for (auto node = head; node; node = node->next)//獲取鏈表中節(jié)點(diǎn)的值,將其保存在values中,以便進(jìn)行處理。{values.push_back(node->val);}vector<int> res(values.size(), 0);for (auto i = 0; i < values.size(); ++i) {//查找目標(biāo)值的過程while (!hole.empty() && values[i] > values[hole.top()]) {res[hole.top()] = values[i];hole.pop();}hole.push(i);}return res;
}
運(yùn)行結(jié)果為:
總結(jié)
- 上一篇: 刷题:二叉树的非递归遍历方式
- 下一篇: 绝句是谁写的呢?