首先记住这句话,笔试都遇到好几次了:
从数据结构角度看,栈也是线性表!
目录
Leetcode150.逆波兰表达式求值
最经典的一道栈的题目,想当年为了弄懂这题可是花了不少劲,现在看来实属easy!
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(int i=0;i<tokens.size();i++){
if(tokens[i]=="+"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a+b);
}else if(tokens[i]=="-"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(b-a);
}else if(tokens[i]=="*"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(a*b);
}else if(tokens[i]=="/"){
int a = st.top();
st.pop();
int b = st.top();
st.pop();
st.push(b/a);
}else{
st.push(stoi(tokens[i]));
}
}
return st.top();
}
};
LeetCode1021.删除最外层的括号
这题真妙啊,要不是看了评论区,怎么也不会想到可以用栈来求解!
class Solution {
public:
string removeOuterParentheses(string S) {
string res = "";
stack<char> mystack;
for (int i = 0; i < S.size(); i++) {
if (S[i] == ')')
mystack.pop();
if (!mystack.empty())
res+=S[i];
if (S[i] == '(')
mystack.push('(');
}
return res;
}
};
LeetCode921.使括号有效的最少添加
这题是上面那题的姊妹版,同样用栈stack解决,但是注意先判断栈是否为空!
class Solution {
public:
int minAddToMakeValid(string S) {
stack<char> s;
for(int i=0;i<S.size();i++){
if(S[i]=='('||s.empty())//先判断栈是否为空
s.push(S[i]);
else if(S[i]==')'&&s.top()=='(')
s.pop();
else
s.push(S[i]);
}
return s.size();
}
};
LeetCode1047.删除字符串中的所有相邻重复项
想一下没有再比这个更明显的栈结构模拟的了……
进阶一点的逆波兰算法:栈解逆波兰算法
class Solution {
public:
string removeDuplicates(string S) {
stack<char> s;
s.push(-1);//开头放进一个不可能的元素放置后面地址错误
for(int i=0;i<S.size();i++){
if(S[i]!=s.top())
s.push(S[i]);
else
s.pop();
}
string ss;
int size = s.size();
for(int i=0;i<size-1;i++){
ss.push_back(s.top());
s.pop();
}
reverse(ss.begin(),ss.end());//结果需要反转
return ss;
}
};
LeetCode面试题03.04.化栈为队
用两个栈来模拟队列,是一个十分经典的栈与队列问题!
class MyQueue {
public:
/** Initialize your data structure here. */
stack<int> s1,s2;//s1记录队列的压入顺序,s2作转换使用
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
//因为每次pop或者peek的时候都改变了s1,所以push的时候要将s2中的倒回s1
while(!s2.empty()){
s1.push(s2.top());
s2.pop();
}
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int ans = s2.top();
s2.pop();
return ans;
}
/** Get the front element. */
int peek() {
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return s1.empty()&&s2.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
另一种写法:
class MyQueue {
public:
/** Initialize your data structure here. */
//s1记录队列的压入顺序,s2作转换使用;因此s2和s1是逆序的
stack<int> s1,s2;
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
if(s2.empty()){//说明s2没有被操作过,操作一遍
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
}
int ans = s2.top();
s2.pop();
return ans;
}
/** Get the front element. */
int peek() {
if(s2.empty()){
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
}
return s2.top();
}
/** Returns whether the queue is empty. */
bool empty() {
return s1.empty()&&s2.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
LeetCode682.棒球比赛
典型的栈,会逆波兰算法,这个很快就会有思路
class Solution {
public:
int calPoints(vector<string>& ops) {
stack<int> s;
for(int i=0;i<ops.size();i++){
if(ops[i]=="+"){
int a = s.top();
s.pop();
int b = s.top();
s.push(a);
s.push(a+b);
}else if(ops[i]=="C"){
s.pop();
}else if(ops[i]=="D"){
int c = s.top();
s.push(2*c);
}else{
//牢记将string转换成int的方法!
s.push(stoi(ops[i]));
}
}
int ans = 0;
while(!s.empty()){
ans+=s.top();
s.pop();
}
return ans;
}
};
LeetCode496.下一个更大的元素I
感觉不用用栈就可以做啊
官方题解用单调栈+hashmap,有点小题大做了
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> v;
for(int i=0;i<nums1.size();i++){
bool flag = true;
for(int j = 0;j<nums2.size();j++)
if(nums2[j]==nums1[i])
for(int k = j+1;k<nums2.size();k++)
if(nums2[k]>nums1[i]){
v.push_back(nums2[k]);
flag = false;
break;
}
if(flag)
v.push_back(-1);
}
return v;
}
};