介绍
栈和队列是STL(C++标准库)里面的两个数据结构。
-
HP STL 其他版本的C++ STL,一般是以HP STL为蓝本实现出来的,HP STL是C++ STL的第一个实现版本,而且开放源代码。
-
P.J.Plauger STL 由P.J.Plauger参照HP STL实现出来的,被Visual C++编译器所采用,不是开源的。
-
SGI STL 由Silicon Graphics Computer Systems公司参照HP STL实现,被Linux的C++编译器GCC所采用,SGI STL是开源软件,源码可读性甚高。
栈和队列也是SGI STL里面的数据结构
stack
- push(): 在栈顶添加一个元素。
- pop(): 移除栈顶元素。
- top(): 返回栈顶元素的引用,但不移除它。
- empty():检查栈是否为空。
- size(): 返回栈中元素的数量。
queue
- empty(): 检查队列是否为空。
- size(): 返回队列中的元素数量。
- front(): 返回队首元素的引用。
- back(): 返回队尾元素的引用。
- push(): 在队尾添加一个元素。
- pop(): 移除队首元素。
232.用栈实现队列
题目链接
状态:基本功
class MyQueue {
public:
stack<int> sin;
stack<int> sout;
MyQueue() {
}
void push(int x) {
sin.push(x);
}
int pop() {
if(sout.empty()){
while(!sin.empty()){
sout.push(sin.top());
sin.pop();
}
}
int t=sout.top();
sout.pop();
return t;
}
int peek() {
int x=pop();
sout.push(x);
return x;
}
bool empty() {
return sin.empty()&&sout.empty();
}
};
225. 用队列实现栈
题目链接
状态:基本功
class MyStack {
public:
queue<int> q;
MyStack() {
}
void push(int x) {
q.push(x);
}
int pop() {
int n=q.size()-1;
while(n--){
q.push(q.front());
q.pop();
}
int t=q.front();
q.pop();
return t;
}
int top() {
return q.back();
}
bool empty() {
return q.empty();
}
};
20. 有效的括号
题目链接
状态:错一次
错误原因:匹配前未检查栈是否为空
class Solution {
public:
bool isValid(string s) {
int n = s.size();
if (n % 2 != 0)
return false;
stack<char> st;
char t;
for (char i : s) {
if (i == '(' || i == '[' || i == '{')
st.push(i);
else if (!st.empty() && ((i == ')' && st.top() == '(') ||
(i == ']' && st.top() == '[') ||
(i == '}' && st.top() == '{'))) {
st.pop();
} else
return false;
}
return st.empty();
}
};
改进版本
见前括号,push相应的后括号,然后匹配时直接对比是否相同(其实思路一样)
class Solution {
public:
bool isValid(string s) {
if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求
stack<char> st;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') st.push(')');
else if (s[i] == '{') st.push('}');
else if (s[i] == '[') st.push(']');
// 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
// 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
else if (st.empty() || st.top() != s[i]) return false;
else st.pop(); // st.top() 与 s[i]相等,栈弹出元素
}
// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
return st.empty();
}
};
1047. 删除字符串中的所有相邻重复项
题目链接
状态:错一次
错误原因:reverse参数写错
class Solution {
public:
string removeDuplicates(string s) {
stack<char> st;
for (char i : s) {
if (st.empty()) {
st.push(i);
} else if (st.top() != i) {
st.push(i);
} else if (!st.empty() || st.top() == i) {
st.pop();
}
}
string ans = "";
while (!st.empty()) {
ans += st.top();
st.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
};
官解:直接拿字符串当栈!
class Solution {
public:
string removeDuplicates(string S) {
string result;
for(char s : S) {
if(result.empty() || result.back() != s) {
result.push_back(s);
}
else {
result.pop_back();
}
}
return result;
}
};