leetcode刷题记录---栈实用篇10/7---对应题目编号20,155,232,844,224,682,496

本文深入探讨了数据结构中的栈、队列、最小栈的概念与应用,包括有效的括号匹配、用栈实现队列、比较含退格的字符串等算法问题。同时,详细解析了基本计算器的计算逻辑和棒球比赛计分系统的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }
};

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值