代码随想录算法训练营第11天| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

代码随想录算法训练营第11天| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

2024-3-24
这几天复习了408王道数据结构的栈和队列部分,刚好最近也要准备蓝桥杯,因此重新开始训练营学习,顺便巩固学习成果。

20. 有效的括号

题目链接:20. 有效的括号
文档讲解:20. 有效的括号
视频讲解:
目标:
状态:

学习前的想法

左括号进栈,遇到右括号就和栈顶左括号进行比较,相配则继续,不相配则返回false。

如果遇到右括号,但此时栈中没有左括号,也直接返回false。

遍历完字符串后,如果栈空,则说明全部相符,否则有多余的括号。

class Solution {
public:
    bool isValid(string s) {
        stack<char> stack;
        for(int i = 0; i < s.size(); i++) {
            if(s[i] == '(' || s[i] == '[' || s[i] == '{') stack.push(s[i]);

            if(s[i] == ')') {
                if(stack.empty()) return false;
                if(stack.top() == '(') stack.pop();
                else return false;
            }
            if(s[i] == ']') {
                if(stack.empty()) return false;
                if(stack.top() == '[')  stack.pop();
                else return false;
            }
            if(s[i] == '}') {
                if(stack.empty()) return false;
                if(stack.top() == '{') stack.pop();
                else return false;
            }
        }

        if(stack.empty()) return true;

        return false;
    }
};

2024-3-24
成功ac

学习后的想法

括号匹配是使用栈解决的经典问题。

由于栈结构的特殊性,非常适合做对称匹配类的题目。

在写这种模拟类的题目的时候,一定要先分析好所有的情况,这样才能避免写的过程中混乱。

实现

代码随想录的实现基本上和我的实现一样,但是用了一些小技巧,可以减少判断次数。

1047. 删除字符串中的所有相邻重复项

题目链接:1047. 删除字符串中的所有相邻重复项
文档讲解:1047. 删除字符串中的所有相邻重复项
视频讲解:
目标:
状态:

学习前的想法

题目给出一个由小写字母组成的字符串s,我们需要重复比较字符串中相邻的两个字符,如果相同,就把它们都删除。

例如输入字符串abbaca对应的输出字符串为ca

我采用栈来处理这种问题,字符串首元素进栈,之后每个元素与栈顶元素作比较,相等则弹出栈顶元素,否则该元素进栈,遍历字符串完毕后,输出栈中所有元素。

尝试实现代码:

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> s1;
        stack<char> s2;

        for(int i = 0; i < s.size(); i++) {
            if(s1.empty()) s1.push(s[i]);
            else {
                if(s[i] == s1.top()) s1.pop();
                else s1.push(s[i]);
            }
        }

        while(!s1.empty()) {
            s2.push(s1.top());
            s1.pop();
        }

        string n = "";

        while(!s2.empty()) {
            n += s2.top();
            s2.pop();
        }

        return n;
    }
};

2024-3-25
成功ac,但是最后怎么把栈中的字符全部去除是一个值得注意的点,我的方法很蠢,又声明了一个栈来重新排序。

学习后的想法

基本和我思路一致,学到了可以使用reverse()函数来翻转字符串。

同时学到了,可以直接使用string来模拟一个栈,这样最后就不需要再进行出栈,反转字符串的操作了。

实现

这里给出使用string来模拟栈的代码:

string result;
for(char s : S) {
	if(result.empty() || result.back() != s) {
		result.push_back(s);
	}else {
		result.pop_back();
	}
	
	return result;
}

150. 逆波兰表达式求值

题目链接:150. 逆波兰表达式求值
文档讲解:150. 逆波兰表达式求值
视频讲解:
目标:
状态:

学习前的想法

这几天在复习数据结构的时候,学到了这里。

根据王道讲解,波兰表达式为前缀表达式,逆波兰表达式实际上就是后缀表达式,这两者的区别是运算符号前者会安置在表达式左侧即前缀,而后者会安置在右侧,即后缀。这样可以明确每个运算符的运算顺序,而不需要使用括号来进行认为划分,更方便计算机处理。

我们平常使用的实际上是中缀表达式。

准备一个栈用来存储数字,对于一个给定的逆波兰表达式,对其进行遍历,遇到数字则进栈,遇到运算符则从栈中弹出两个数进行运算,先弹出的数为右操作数,将算出的结果入栈。

尝试实现代码:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> stack;
        int right,left;

        for(string s : tokens) {
            if(s == "+") {
                right = stack.top();
                stack.pop();
                left = stack.top();
                stack.pop();
                stack.push(left + right);
            }
            else if(s == "-") {
                right = stack.top();
                stack.pop();
                left = stack.top();
                stack.pop();
                stack.push(left - right);
            }
            else if(s == "*") {
                right = stack.top();
                stack.pop();
                left = stack.top();
                stack.pop();
                stack.push(left * right);
            }
            else if(s == "/") {
                right = stack.top();
                stack.pop();
                left = stack.top();
                stack.pop();
                stack.push(left / right);
            }
            else {
                stack.push(stoi(s));
            }
        }

        return stack.top();
    }
}

2024-3-27
由于不知道如何将字符串转换为int整型,我上网查询到stoi()函数可以直接实现。

学习后的想法

和我思路基本一致。

今天学习数据结构的时候也学到了二叉树的前中后序遍历,逆波兰表达式实际上相当于是二叉树中的后续遍历。可以把运算符当作中间节点构造一棵二叉树,实际上编译原理里的语义分析树好像也是这样得来的🤔。

实现

卡哥的实现和我基本一样,不过使用了long long防止溢出,然后字符串转为整型的函数用的和我搜索到的也是一样的stoll(),因为卡哥用的long long 所以是ll。

收获与学习时长

学习时长: h min
没有计算具体的时间,不过也许是因为前几天刚复习国408数据结构栈与队列的原因,还是比较轻松的。

收获

熟练了书本上知识的代码实现,思路变得更清晰。

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值