20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

简介: 本内容涵盖三道编程题的题目与题解,包括“有效的括号”(使用栈判断括号是否匹配)、“删除字符串中的所有相邻重复项”(利用栈删除相邻重复字符)以及“逆波兰表达式求值”(通过栈计算后缀表达式的结果)。每道题均采用C++实现,详细展示了栈在解决匹配问题、字符串处理和表达式求值中的应用。代码逻辑清晰,适合学习栈数据结构的应用场景与实现方法。

题目:20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

左括号必须以正确的顺序闭合。

每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"

输出:true

示例 2:

输入:s = "()[]{}"

输出:true

示例 3:

输入:s = "(]"

输出:false

提示:

1 <= s.length <= 104

s 仅由括号 '()[]{}' 组成

题解:

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. 删除字符串中的所有相邻重复项

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"

输出:"ca"

解释:

例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

1 <= S.length <= 20000

S 仅由小写英文字母组成。

题解:

class Solution {
public:
    string removeDuplicates(string S) {
        stack<char> st;
        for (char s : S) {
            if (st.empty() || s != st.top()) {
                st.push(s);
            } else {
                st.pop(); // s 与 st.top()相等的情况
            }
        }
        string result = "";
        while (!st.empty()) { // 将栈中元素放到result字符串汇总
            result += st.top();
            st.pop();
        }
        reverse (result.begin(), result.end()); // 此时字符串需要反转一下
        return result;
 
    }
};

题目:150. 逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

有效的算符为 '+'、'-'、'*' 和 '/' 。

每个操作数(运算对象)都可以是一个整数或者另一个表达式。

两个整数之间的除法总是 向零截断 。

表达式中不含除零运算。

输入是一个根据逆波兰表示法表示的算术表达式。

答案及所有中间计算结果可以用 32 位 整数表示。

示例 1:

输入:tokens = ["2","1","+","3","*"]

输出:9

解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = ["4","13","5","/","+"]

输出:6

解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]

输出:22

解释:该算式转化为常见的中缀算术表达式为:

 ((10 * (6 / ((9 + 3) * -11))) + 17) + 5

= ((10 * (6 / (12 * -11))) + 17) + 5

= ((10 * (6 / -132)) + 17) + 5

= ((10 * 0) + 17) + 5

= (0 + 17) + 5

= 17 + 5

= 22

提示:

1 <= tokens.length <= 104

tokens[i] 是一个算符("+"、"-"、"*" 或 "/"),或是在范围 [-200, 200] 内的一个整数

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。

适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中

题解:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        // 力扣修改了后台测试数据,需要用longlong
        stack<long long> st;  
        for (int i = 0; i < tokens.size(); i++) {
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
                long long num1 = st.top();
                st.pop();
                long long num2 = st.top();
                st.pop();
                if (tokens[i] == "+") st.push(num2 + num1);
                if (tokens[i] == "-") st.push(num2 - num1);
                if (tokens[i] == "*") st.push(num2 * num1);
                if (tokens[i] == "/") st.push(num2 / num1);
            } else {
                st.push(stoll(tokens[i]));
            }
        }
 
        int result = st.top();
        st.pop(); // 把栈里最后一个元素弹出(其实不弹出也没事)
        return result;
    }
};
相关文章
|
自然语言处理 语音技术 开发者
开源上新|FunASR多语言离线文件转写软件包
开源上新|FunASR多语言离线文件转写软件包
|
Kubernetes 应用服务中间件 API
5 分钟了解 Kubernetes Ingress 和 Gateway API
5 分钟了解 Kubernetes Ingress 和 Gateway API
1496 0
|
5月前
|
算法
77. 组合
回溯法是一种通过递归搜索解决问题的算法,适用于组合、切割、子集、排列和棋盘等问题。以“77. 组合”为例,给定整数n和k,需找出[1, n]中所有可能的k个数的组合。此问题可抽象为树形结构,n为树宽,k为树深。通过递归与回溯,每次从集合中选取元素并调整范围,当路径长度等于k时收集结果。题解中使用`backtracking`函数实现递归,利用`path`记录当前组合,最终返回所有符合条件的结果。
|
5月前
|
算法 C++
530.二叉搜索树的最小绝对差 ,501.二叉搜索树中的众数 ,236. 二叉树的最近公共祖先
本内容涵盖了三道二叉树相关的问题及其解法,涉及二叉搜索树的最小绝对差、二叉搜索树中的众数以及二叉树的最近公共祖先。通过中序遍历将二叉搜索树转化为有序数组以求最小差值;利用哈希表统计节点值频率并排序找出众数;通过递归方法寻找二叉树中两节点的最近公共祖先。这些题目展示了二叉树遍历、递归及数据结构应用的核心思想,是深入理解二叉树算法的重要实践。
|
开发者 黑灰产治理
专家博主最新专享福利上线!发文即得积分好礼!
最新专享福利上线!赢取海量积分兑换心仪礼品
725 0
|
5月前
|
机器学习/深度学习 人工智能 PyTorch
200行python代码实现从Bigram模型到LLM
本文从零基础出发,逐步实现了一个类似GPT的Transformer模型。首先通过Bigram模型生成诗词,接着加入Positional Encoding实现位置信息编码,再引入Single Head Self-Attention机制计算token间的关系,并扩展到Multi-Head Self-Attention以增强表现力。随后添加FeedForward、Block结构、残差连接(Residual Connection)、投影(Projection)、层归一化(Layer Normalization)及Dropout等组件,最终调整超参数完成一个6层、6头、384维度的“0.0155B”模型
309 11
200行python代码实现从Bigram模型到LLM
|
5月前
|
SQL 存储 缓存
Fluss 实战:用 Partial Update 构建实时宽表的新范式
传统流式数据管道通过多表 Join 构建宽表,如实时推荐引擎需整合用户偏好、购买记录等8个数据源,但此方法在大规模场景下状态管理复杂、资源消耗高且调试困难。Fluss 提出部分更新方案,基于主键将各数据源独立写入共享宽表,避免复杂 Join 操作。示例中,通过 Flink SQL 创建推荐、曝光、点击等表,并逐步插入数据实现宽表构建。最终,借助 Fluss 的高效合并机制,输出包含最新信息的统一视图,提升可扩展性和维护性。
294 8
Fluss 实战:用 Partial Update 构建实时宽表的新范式
|
5月前
|
安全 数据可视化 Linux
在线游戏的地基:VPS和专用服务器性价比大比拼!
游戏服务器是在线游戏的基石,选择合适的服务器类型对玩家体验至关重要。本文对比了VPS(虚拟专用服务器)和专用服务器的优劣势:VPS经济灵活、易于管理,但性能和安全存在局限,适合预算有限或玩家规模适中的游戏;专用服务器性能强大、安全可靠且可控性高,但成本和技术门槛较高,更适合大型MMO或竞技游戏。根据游戏类型、预算、技术能力和扩展需求,合理选择服务器类型是关键。初创阶段可选用中端VPS,成长阶段考虑高端VPS或低端专用服务器,成熟阶段则需高端专用服务器集群。未来,混合架构或将实现性能与成本的平衡。最终,以玩家流畅体验为导向,选择最适合的服务器方案。
198 3
|
存储 Linux 开发工具
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
5847 1
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
|
5月前
|
存储 缓存 数据挖掘
阿里云服务器实例选购指南:经济型、通用算力型、计算型、通用型、内存型性能与适用场景解析
当我们在通过阿里云的活动页面挑选云服务器时,相同配置的云服务器通常会有多种不同的实例供我们选择,并且它们之间的价格差异较为明显。这是因为不同实例规格所采用的处理器存在差异,其底层架构也各不相同,比如常见的X86计算架构和Arm计算架构。正因如此,不同实例的云服务器在性能表现以及适用场景方面都各有特点。为了帮助大家在众多实例中做出更合适的选择,本文将针对阿里云服务器的经济型、通用算力型、计算型、通用型和内存型实例,介绍它们的性能特性以及对应的使用场景,以供大家参考和选择。