栈和队列的基本操作
栈stack
数据存取:
数据存取:
-
push(elem);
//向栈顶添加元素 -
pop();
//从栈顶移除第一个元素 -
top();
//返回栈顶元素
大小操作:
-
empty();
//判断堆栈是否为空 -
size();
//返回栈的大小
队列queue
数据存取:
-
push(elem);
//往队尾添加元素 -
pop();
//从队头移除第一个元素 -
back();
//返回最后一个元素 -
front();
//返回第一个元素
大小操作:
-
empty();
//判断堆栈是否为空 -
size();
//返回栈的大小
双端队列deque
大小操作:
-
deque.empty();
//判断容器是否为空 -
deque.size();
//返回容器中元素的个数 -
deque.resize(num);
//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。//如果容器变短,则末尾超出容器长度的元素被删除。
-
deque.resize(num, elem);
//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。//如果容器变短,则末尾超出容器长度的元素被删除。
两端插入操作:
-
push_back(elem);
//在容器尾部添加一个数据 -
push_front(elem);
//在容器头部插入一个数据 -
pop_back();
//删除容器最后一个数据 -
pop_front();
//删除容器第一个数据
指定位置操作:
-
insert(pos,elem);
//在pos位置插入一个elem元素的拷贝,返回新数据的位置。 -
insert(pos,n,elem);
//在pos位置插入n个elem数据,无返回值。 -
insert(pos,beg,end);
//在pos位置插入[beg,end)区间的数据,无返回值。 -
clear();
//清空容器的所有数据 -
erase(beg,end);
//删除[beg,end)区间的数据,返回下一个数据的位置。 -
erase(pos);
//删除pos位置的数据,返回下一个数据的位置。
数据存取:
-
front();
//返回容器中第一个数据元素 -
back();
//返回容器中最后一个数据元素
232. 用栈实现队列
class MyQueue {
public:
stack<int> s1;
stack<int> s2;
MyQueue() {
}
void push(int x) {
s1.push(x);
}
int pop() {
if (s2.empty()){
while (!s1.empty()){
s2.push(s1.top());
s1.pop();
}
}
int result = s2.top();
s2.pop();
return result;
}
int peek() {
if (s2.empty()){
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
}
return s2.top();
}
bool empty() {
if (s1.empty() && s2.empty()){
return true;
} else {
return false;
}
}
};
225. 用队列实现栈
deque写法
当时没想出来单个queue的写法,就走了捷径,deque本身就可以当做一个stack使用
class MyStack {
public:
deque<int> stk;
MyStack() {
}
void push(int x) {
stk.push_back(x);
}
int pop() {
int result = stk.back();
stk.pop_back();
return result;
}
int top() {
return stk.back();
}
bool empty() {
return stk.empty();
}
};
单queue写法
pop:将queue的前size - 1个(不包含queue的末尾元素)插入到queue末尾,然后将对头元素pop(也就是原始queue 的末尾元素)
class MyStack {
public:
queue<int> que;
MyStack() {
}
void push(int x) {
que.push(x);
}
int pop() {
int size = que.size();
size--;
while (size--){
que.push(que.front());
que.pop();
}
int result = que.front();
que.pop();
return result;
}
int top() {
return que.back();
}
bool empty() {
return que.empty();
}
};
20. 有效的括号
简单易懂版
遇到左括号就进栈,如果遇到右括号,则判断是否有左括号进行匹配(此时要判断栈是否为空,如果为空则说明有多余的括号,直接return false),若匹配则pop栈顶元素,否则return false。最后如果栈空则正确。
class Solution {
public:
bool isValid(string s) {
stack<char> t;
int len=s.size();
if(len % 2 != 0) return false;
for(int i = 0; i < len; i++){
if(s[i]=='('||s[i]=='['||s[i]=='{'){
t.push(s[i]);
}else{
switch(s[i]){
case ']':
if(!t.empty() &&t.top()=='[') t.pop();
else return false;
break;
case '}':
if(!t.empty() &&t.top()=='{') t.pop();
else return false;
break;
case ')':
if(!t.empty() &&t.top()=='(') t.pop();
else return false;
break;
}
}
}
if(t.empty())return true;
else return false;
}
};
map集合+栈
定义一个map集合pairs和栈stk,集合里面存放括号对,key为右括号,value为左括号,遍历字符串,遇到左括号直接进栈(只有左括号进栈,右括号仅限于匹配),如果遇到右括号,则判断栈顶是否为匹配的左括号,若是则pop,否则false,最后如果栈内没有多余的左括号,则匹配成功。
class Solution {
public:
bool isValid(string s) {
int n = s.size();
//若字符串长度为奇数,永远不可能匹配
if (n % 2 == 1) {
return false;
}
unordered_map<char, char> pairs = {
{')', '('},
{']', '['},
{'}', '{'}
};
stack<char> stk;
for (char ch: s) {
//遇到右括号,count是匹配的key
if (pairs.count(ch)) {
//若栈为空或栈顶元素和value值不匹配,则false
if (stk.empty() || stk.top() != pairs[ch]) {
return false;
}
stk.pop();
}
else {
//左括号入栈
stk.push(ch);
}
}
return stk.empty();
}
};
代码随想录版
有三种不匹配的情况,
1.第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
2.第二种情况,括号没有多余,但是 括号的类型没有匹配上。
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
3.第三种情况,字符串里右方向的括号多余了,所以不匹配。
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
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. 删除字符串中的所有相邻重复项
定义一个栈stk,如果栈不为空或者当前遍历的字符s[i]与栈顶元素不同,则将字符压入栈顶;否则,栈顶元素出栈。将此时栈中元素再逆序输出就是结果串。
class Solution {
public:
string removeDuplicates(string s) {
stack<char> stk;
string result = "";
for (int i = 0; i < s.size(); i++){
if (!stk.empty() && s[i] == stk.top()){
stk.pop();
}else {
stk.push(s[i]);
}
}
while (!stk.empty()){
result += stk.top();
stk.pop();
}
reverse(result.begin(), result.end());
return result;
}
};