1.有效的括号
bool isPipei(char s1,char s2){
if((s1 == '{'&&s2 == '}')||(s1 == '('&&s2 == ')')||(s1 == '['&&s2 == ']')){
return true;
}
return false;
}
bool isValid(string s){
stack<char> tmp;
for(auto ch:s){
if(!tmp.empty() && isPipei(tmp.top(),ch)) {tmp.pop();continue;}
else tmp.push(ch);
}
return tmp.empty();
}
2.最小栈
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
deque<int> mindata;
deque<int> data;
}
void push(int x){
data.push_back(x);
if(!mindata.empty()&&mindata.back()<x) mindata.push_back(mindata.back());
else mindata.push_back(x);
}
void pop() {
if(data.size()>0&&mindata.size()>0){
data.pop_back();
mindata.pop_back();
}
}
int top() {
if(data.size()>0) return data.back();
return -1;
}
int getMin() {
if(data.size()>0&&mindata.size()>0){
return mindata.back();
}
return -1;
}
private:
deque<int> mindata;
deque<int> data;
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
3.232用栈实现队列
class MyQueue {
public:
/** Initialize your data structure here. */
MyQueue() {
deque<int> s1;
deque<int> s2;
}
/** Push element x to the back of queue. */
void push(int x) {
s1.push_back(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
int res = 0;
if(!s2.empty()) {res = s2.back();s2.pop_back();}
else if(!s1.empty()&&s2.empty()){
while(!s1.empty()){
s2.push_back(s1.back());
s1.pop_back();
}
res = s2.back();
s2.pop_back();
}
return res;
}
/** Get the front element. */
int peek() {
if(!s2.empty()) {return s2.back();}
else if(!s1.empty()&&s2.empty()){
while(!s1.empty()){
s2.push_back(s1.back());
s1.pop_back();
}
return s2.back();
}
else return -1;
}
/** Returns whether the queue is empty. */
bool empty() {
if(s1.empty()&&s2.empty()) return true;
else return false;
}
private:
deque<int> s1;
deque<int> s2;
};
4.比较含退格的字符串
class Solution {
public:
bool backspaceCompare(string S, string T) {
stack<char> ss;
stack<char> st;
for(auto ch:S){
if(ch == '#'&&ss.empty()) continue;
else if(ch == '#'&&!ss.empty()) ss.pop();
else ss.push(ch);
}
for(auto ch:T){
if(ch == '#'&&st.empty()) continue;
else if(ch == '#'&&!st.empty()) st.pop();
else st.push(ch);
}
while(!ss.empty()&&!st.empty()){
if(ss.top() != st.top()) return false;
ss.pop();
st.pop();
}
return ss.empty()&&st.empty();
}
};
5.224基本计算器
思路:
1.对于字符串s中的每一个字符
1.如果字符是(,那就入栈opers
2.如果字符是),执行opers计算逻辑;(出栈
3.如果字符是+或者-,执行opers计算逻辑;+或-入栈
4.如果字符是数字,提取整数,并入栈data
2.执行opers计算逻辑
只要opers栈不空并且opers栈顶是‘+’或‘-’
b = opers出栈,a=opers出栈,r = a op b
r压入data栈
解题步骤:
1.遍历一遍字符串,把空格去掉
2.定义两个栈,一个装符号一个装数字
3.只要p<y,即这两个指针指向的字符均属于字符串
如果p指向“(”,压入符号栈,p++
除此之外如果p指向“+”,“-”,“)”
只要符号栈不空并且符号栈顶元素为“+”或“-”
数据栈栈顶俩元素取出来,符号栈顶取出。。
根据符号栈顶元素,来选择压入a+b或者a-b
如果p指向“)”
如果符号栈不空并且符号栈顶为“(”,符号出栈
否则就把p指向的字符压入符号栈
p++;
否则 //说明是数字
定义r。只要指针合法并且指针所指字符是数字
r更新为10*r+(s[p++]-'0')
把r压入数据栈
4.只要符号栈不为空
定义a,b分别为数据栈顶元素,op为符号栈栈顶元素
根据op把数据压入数据栈
5.返回数据栈栈顶元素
class Solution {
public:
typedef long long l1;
l1 done(const string &s, int x, int y) {
stack<l1> opands;
stack<char> opors;
int p = x;
while (p<y)
{
if (s[p] == '(') { opors.push(s[p]); ++p; }
else if (s[p] == '+' || s[p] == '-' || s[p] == ')') {
while (opors.size()&&(opors.top()=='+'||opors.top()=='-'))
{
l1 b = opands.top(); opands.pop();
l1 a = opands.top(); opands.pop();
char op = opors.top(); opors.pop();
if (op == '+') opands.push(a + b);
else if (op == '-') opands.push(a - b);
}
if (s[p] == ')') {
if (opors.size() && opors.top() == '(')
opors.pop();
}
else
opors.push(s[p]);
++p;
}
else {
l1 r = 0;
while (p < y&&isdigit(s[p]))
{
r = 10 * r + (s[p++] - '0');
}
opands.push(r);
}
}
while (opors.size()) {
l1 b = opands.top(); opands.pop();
l1 a = opands.top(); opands.pop();
char op = opors.top(); opors.pop();
if (op == '+') opands.push(a + b);
else if (op == '-') opands.push(a - b);
}
return opands.top();
}
int calculate(string s) {
string t;
for (auto x : s) if (x != ' ') t += x;
return done(t, 0, t.size());
}
};
6.棒球比赛 682
你现在是棒球比赛记录员。
给定一个字符串列表,每个字符串可以是以下四种类型之一:
1.整数(一轮的得分):直接表示您在本轮中获得的积分数。
2. "+"(一轮的得分):表示本轮获得的得分是前两轮有效 回合得分的总和。
3. "D"(一轮的得分):表示本轮获得的得分是前一轮有效 回合得分的两倍。
4. "C"(一个操作,这不是一个回合的分数):表示您获得的最后一个有效 回合的分数是无效的,应该被移除。
每一轮的操作都是永久性的,可能会对前一轮和后一轮产生影响。
你需要返回你在所有回合中得分的总和。
示例 1:
输入: ["5","2","C","D","+"]
输出: 30
解释:
第1轮:你可以得到5分。总和是:5。
第2轮:你可以得到2分。总和是:7。
操作1:第2轮的数据无效。总和是:5。
第3轮:你可以得到10分(第2轮的数据已被删除)。总数是:15。
第4轮:你可以得到5 + 10 = 15分。总数是:30。
示例 2:
输入: ["5","-2","4","C","D","9","+","+"]
输出: 27
解释:
第1轮:你可以得到5分。总和是:5。
第2轮:你可以得到-2分。总数是:3。
第3轮:你可以得到4分。总和是:7。
操作1:第3轮的数据无效。总数是:3。
第4轮:你可以得到-4分(第三轮的数据已被删除)。总和是:-1。
第5轮:你可以得到9分。总数是:8。
第6轮:你可以得到-4 + 9 = 5分。总数是13。
第7轮:你可以得到9 + 5 = 14分。总数是27。
注意:
输入列表的大小将介于1和1000之间。
列表中的每个整数都将介于-30000和30000之间
class Solution {
public:
int calPoints(vector<string>& ops) {
if(ops.size()<1) return 0;
stack<int> tmp;
for(auto i:ops){
if(i == "+"){
int temp = tmp.top();
tmp.pop();
int newtop = tmp.top()+temp;
tmp.push(temp);
tmp.push(newtop);
}
else if(i == "D"){
tmp.push(tmp.top()*2);
}
else if(i == "C"){
tmp.pop();
}
else tmp.push(stoi(i));
}
int ans = 0;
while(tmp.size()){
ans += tmp.top();
tmp.pop();
}
return ans;
}
};
7. 496下一个更大元素
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> res(nums1.size(),-1);
for(int j = 0;j<nums1.size();++j){
int x = nums1[j];
for(int i = 0;i<nums2.size();++i){
if(nums2[i] == x){
for(int k = i+1;k<nums2.size();++k){
if(nums2[k]>x) {res[j] = nums2[k];break;}
}
}
}
}
return res;
}
};