題目:232.用棧實現佇列
思路:
1.使用雙棧,一個作為輸入,一個作為輸出
程式碼:
class MyQueue {
private:
stack<int> A,B;
public:
MyQueue() {
}
void push(int x) {
A.push(x);
}
int pop() { //刪除A棧底元素 並返回元素
int result=this->peek();
B.pop();
return result;
}
int peek() { //獲取A棧底元素
if(B.empty()){
while(!A.empty()){
B.push(A.top());
A.pop();
}
}
return B.top();
}
bool empty() {//最佳化-> return A.empty()&& B.empty;
if(A.empty()&&B.empty())
return true;
else
return false;
}
};
補充:
1.棧和佇列是STL(C++標準庫)裡面的兩個資料結構。常使用SGI STL版(開源,可讀性高,被GCC所採用)。
2.二者以底層容器來實現所有工作,對外提供統一介面,所以二者不是容器,屬於container adapter 容器介面卡。
3.因二者的進出特性,不提供迭代器進行訪問。
棧stack
stack<型別> 變數名;
- 一頭通,先進後出
- 底層實現可使用容器deque,vector,list,沒有指定底層實現,預設deque為預設情況下棧的底層結構
deque是一個雙向佇列,封住一段,只開通另一端就可以實現棧的邏輯了。 - 對外提供介面
push(x) -- 元素 x 入棧、
empty() -- 返回棧是否為空
pop() -- 移除棧頂元素
top() -- 獲取棧頂元素
size() -- 返回棧內元素的大小;
可以指定vector為棧的底層實現,初始化語句如下:
std::stack<int, std::vector<int> > third; // 使用vector為底層容器的棧
佇列queue
- 兩頭通,先進先出
- SGI STL中佇列一樣是以deque為預設情況下的底部結構
- 對外提供介面
push(x) -- 在末尾加入一個元素
empty() -- 如果佇列空則返回真
front() -- 返回第一個元素
pop() -- 刪除第一個元素
back() -- 返回最後一個元素
size() -- 返回佇列中元素的個數
可以指定list 為起底層實現,初始化queue的語句如下:
std::queue<int, std::list<int>> third; // 定義以list為底層容器的佇列
題目:225. 用佇列實現棧
思路:
0.兩個佇列,第二個用來備份除隊尾元素以外的元素
1.兩個佇列,入隊的時候不斷調整,使的後存入的元素在隊首 模擬棧的存入
2.一個佇列實現,頭插尾 ,一直插,最後尾為首 彈出
程式碼:
方法一
class MyStack {
private:
queue<int> queueA,queueB;
public:
MyStack() {
}
void push(int x) { //輸入調整,使得隊首為最新加入的元素 模擬棧
queueB.push(x);
while(!queueA.empty()){
queueB.push(queueA.front());
queueA.pop();
}
while(!queueB.empty()){
queueA.push(queueB.front());
queueB.pop();
}
}
int pop() { //移除並返回隊首元素
int result=queueA.front();
queueA.pop();
return result;
}
int top() {//返回隊首元素
return queueA.front();
}
bool empty() {
return queueA.empty();
}
}; *
方法二
來源隨想錄
class MyStack {
public:
queue<int> que1;
queue<int> que2; // 輔助佇列,用來備份
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
que1.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int size = que1.size();
size--;
while (size--) { // 將que1 匯入que2,但要留下最後一個元素
que2.push(que1.front());
que1.pop();
}
int result = que1.front(); // 留下的最後一個元素就是要返回的值
que1.pop();
que1 = que2; // 再將que2賦值給que1
while (!que2.empty()) { // 清空que2
que2.pop();
}
return result;
}
/** Get the top element. */
int top() {
return que1.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return que1.empty();
}
};
題目:20. 有效的括號
思路:
0.利用棧存入,遇到不同邊的的括號就彈出,左括號新增,右括號彈出
坑:
- 缺少 第一個為右括號的情況 即沒有匹配的括號,此時stack為空
- stack有empty()判空
- 不匹配的情況可以合併一下
class Solution {
public:
bool isValid(string s) {
//奇數 直接false
if(s.size()%2!=0)
return false;
stack <char> stack;
for(char c: s){
//入棧時直接存入對應的右括號 方便比較
if(c=='(') stack.push(')');
else if(c=='{') stack.push('}');
else if(c=='[') stack.push(']');
else if(c==')'||c=='}'||c==']'){
//不透過,缺少第一個為右括號的情況, 最佳化一下,合併不相等的情況
if(stack.size()==0||c!=stack.top())
return false;
if(c==stack.top())
stack.pop();
}
}
return stack.empty();
/* 囉嗦,已經有empty了啊
if(stack.size()==0)
return true;
else
return false;
*/
}
};
題目:1047. 刪除字串中的所有相鄰重複項
思路:
- 利用棧,比較存入元素和棧頂元素是否相等,相等刪除,最後將棧內的結果存入新的字串中,別忘了翻轉,棧是後進先出
時間複雜度: O(n)
空間複雜度: O(n)
坑:
- reveres();
class Solution {
public:
string removeDuplicates(string s) {
stack<char> stack;
for(char c: s){
if(stack.size()!=0&&c==stack.top())
stack.pop();
else
stack.push(c);
}
//啊哈,棧存入字串是倒序,那麼翻轉就解決了
string result;
while(!stack.empty()){
result.push_back(stack.top());
stack.pop();
}
reverse(result.begin(),result.end());
return result;
}
};
補充:
reverse(s.begin(),s.end())是C++庫函式
今日總結
涉及左右,相鄰匹配的問題,使用棧