当前位置: 首页 > news >正文

LeetCode题练习与总结:基本计算器 Ⅱ--227

一、题目描述

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

整数除法仅保留整数部分。

你可以假设给定的表达式总是有效的。所有中间结果将在 [-2^31, 2^31 - 1] 的范围内。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

示例 1:

输入:s = "3+2*2"
输出:7

示例 2:

输入:s = " 3/2 "
输出:1

示例 3:

输入:s = " 3+5 / 2 "
输出:5

提示:

  • 1 <= s.length <= 3 * 10^5
  • s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
  • s 表示一个 有效表达式
  • 表达式中的所有整数都是非负整数,且在范围 [0, 2^31 - 1] 内
  • 题目数据保证答案是一个 32-bit 整数

二、解题思路

这个问题可以使用栈(stack)来解决。我们使用两个栈,一个用于存储操作数,另一个用于存储操作符。遍历字符串s,根据遇到的字符类型(数字、操作符或空格)进行相应的处理。

  1. 当遇到数字时,将其转换为整数并存储在操作数栈中。
  2. 当遇到操作符时,需要考虑操作符的优先级。如果当前操作符的优先级高于栈顶操作符的优先级,则直接将当前操作符入栈。否则,需要先计算栈顶的操作符,并将结果重新入栈,然后比较当前操作符与新的栈顶操作符的优先级。
  3. 当遇到空格时,忽略它。
  4. 对于乘法和除法,因为它们的优先级高于加法和减法,所以一旦遇到乘号或除号,需要立即计算结果,并将结果入栈。
  5. 对于加法和减法,可以直接将操作数入栈,因为它们可以在最后一起计算。

以下是具体的步骤:

  • 初始化两个栈:一个用于存储操作数(nums),另一个用于存储操作符(ops)。
  • 遍历字符串s,对于每个字符c
    • 如果c是空格,则忽略。
    • 如果c是数字,则解析出完整的数字并压入nums栈。
    • 如果c是操作符(+-*/):
      • 如果ops栈为空或者栈顶的操作符是(,则直接将c压入ops栈。
      • 如果c*/,则从nums栈中弹出两个操作数进行计算,并将结果压回nums栈。
      • 如果c+-,并且ops栈顶不是(,则从nums栈中弹出两个操作数进行计算,并将结果压回nums栈,然后将c压入ops栈。
  • 遍历完成后,如果ops栈中还有操作符,则继续从nums栈中弹出操作数进行计算,直到ops栈为空。
  • 最后,nums栈中的唯一元素即为表达式的结果。

三、具体代码

import java.util.Stack;public class Solution {public int calculate(String s) {Stack<Integer> nums = new Stack<>();Stack<Character> ops = new Stack<>();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == ' ') continue;if (Character.isDigit(c)) {int num = 0;while (i < s.length() && Character.isDigit(s.charAt(i))) {num = num * 10 + (s.charAt(i) - '0');i++;}i--; // since the for loop also increments inums.push(num);} else if (c == '(') {ops.push(c);} else if (c == ')') {while (ops.peek() != '(') {nums.push(applyOp(ops.pop(), nums.pop(), nums.pop()));}ops.pop();} else if (c == '+' || c == '-' || c == '*' || c == '/') {while (!ops.isEmpty() && hasPrecedence(c, ops.peek())) {nums.push(applyOp(ops.pop(), nums.pop(), nums.pop()));}ops.push(c);}}while (!ops.isEmpty()) {nums.push(applyOp(ops.pop(), nums.pop(), nums.pop()));}return nums.pop();}public boolean hasPrecedence(char op1, char op2) {if (op2 == '(' || op2 == ')') return false;if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false;return true;}public int applyOp(char op, int b, int a) {switch (op) {case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': return a / b;}return 0;}
}

请注意,代码中的applyOp方法假设栈中的操作数顺序是正确的,并且对于减法和除法,ab的顺序很重要(a是被操作数,b是操作数)。代码也处理了括号的情况,确保在遇到右括号时,所有括号内的表达式都会被计算。

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 遍历字符串s:假设字符串s的长度为n,则遍历字符串的时间复杂度为O(n)
  • 解析数字:在遍历过程中,每次遇到数字,需要解析出完整的数字。在最坏的情况下,数字可能连续出现,这意味着对于每个数字字符,我们需要进行一次操作。因此,解析数字的总操作次数也是O(n)
  • 应用操作符:在遍历字符串的过程中,每次遇到操作符,我们可能需要从栈中弹出元素进行计算,然后将结果压回栈中。在最坏的情况下,可能需要对每个操作符都进行这样的操作。由于每个操作符最多被处理一次,因此这一步的时间复杂度也是O(n)

综上所述,总的时间复杂度为O(n),其中n是字符串s的长度。

2. 空间复杂度
  • 操作数栈nums:在最坏的情况下,所有数字都直接入栈,没有进行任何计算,因此栈的大小可能达到O(n)
  • 操作符栈ops:在最坏的情况下,所有操作符都直接入栈,没有进行任何计算,因此栈的大小可能达到O(n)

综上所述,总的空间复杂度为O(n),其中n是字符串s的长度。

这里的O(n)表示算法的复杂度与输入字符串的长度成线性关系。在实际情况中,由于数字不会连续占据整个字符串,操作符栈和操作数栈的大小通常会小于n,但最坏情况下的复杂度分析仍然是O(n)

五、总结知识点

  • 栈(Stack)的使用

    • 栈是一种后进先出(Last In First Out, LIFO)的数据结构。
    • 在Java中,Stack类是java.util包中的一个类,用于实现栈数据结构。
  • 字符和字符串操作

    • 使用char类型来处理单个字符。
    • 使用String类的charAt方法来获取字符串中指定位置的字符。
    • 使用Character.isDigit方法来判断一个字符是否是数字。
  • 数字解析

    • 通过循环和字符减去’0’的方式,将字符串中的连续数字字符转换为整数。
  • 运算符优先级

    • 在处理算术表达式时,需要根据运算符的优先级来决定计算的顺序。
    • 使用hasPrecedence方法来判断当前运算符与栈顶运算符的优先级关系。
  • 条件逻辑

    • 使用if-else语句来处理不同类型的字符(空格、数字、运算符、括号)。
    • 使用while循环来处理连续的数字字符,以及应用运算符。
  • 异常处理

    • 虽然在给出的代码中没有显示异常处理,但在实际应用中,应当考虑除法操作可能导致的ArithmeticException(如除以零)。
  • 递归下降

    • 在处理括号时,实际上隐式地使用了递归下降解析的原理,通过递归地将括号内的表达式视为一个子表达式来处理。
  • 运算符应用

    • 使用applyOp方法来根据运算符执行相应的算术运算。
  • 算法逻辑

    • 理解和实现一个基本的算术表达式求值算法,这涉及到算法设计的基本概念。
  • 类型转换

    • 在将字符转换为整数时,涉及到从charint的类型转换。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

相关文章:

LeetCode题练习与总结:基本计算器 Ⅱ--227

一、题目描述 给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。 整数除法仅保留整数部分。 你可以假设给定的表达式总是有效的。所有中间结果将在 [-2^31, 2^31 - 1] 的范围内。 注意&#xff1a;不允许使用任何将字符串作为数学表达式计算…...

Elasticsearch基础(七):Logstash如何开启死信队列

文章目录 Logstash如何开启死信队列 一、确保 Elasticsearch 输出插件启用 DLQ 支持 二、配置 Logstash DLQ 设置 三、查看死信队列 四、排查 CSV 到 Elasticsearch 数据量不一致的问题 Logstash如何开启死信队列 在 Logstash 中&#xff0c;死信队列&#xff08;Dead Le…...

c语言--力扣简单题目(链表的中间节点)讲解

题目如下&#xff1a; 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点…...

【STM32 Blue Pill编程】-定时器计数模式

定时器计数模式 文章目录 定时器计数模式1、定时器计数模式介绍2、硬件准备及接线3、模块配置3.1 定时器计数模式配置3.2 定时器中断配置3.3 串口配置4、代码实现在本文中,我们将讨论如何在计数器模式下配置 STM32 Blue Pill 定时器模块。 要将定时器用作计数器,我们将其配置…...

【例题】lanqiao1331 二进制中 1 的个数

二进制中 1 的个数 题目描述 给定一个整数 x&#xff0c;输出该数二进制表示中 1 的个数。 例&#xff1a;9 的二进制表示为 1001&#xff0c;有 2 位是 1 &#xff0c;所以函数返回 2。 输入描述 输入 x​ &#xff08;内存空间为 32 位的整数&#xff09;。 输出描述 第一…...

【论文解读】图像序列识别:CRNN技术在场景文本识别中的应用与突破(附论文地址)

论文地址&#xff1a;https://arxiv.org/pdf/1507.05717 这篇文章的标题是《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》&#xff0c;作者是Baoguang Shi, Xiang Bai和Cong Yao&#xff0c…...

Vue3+CesiumJS相机定位camera

new Cesium.Camera (scene) 摄像机由位置&#xff0c;方向和视锥台定义。 方向与视图形成正交基准&#xff0c;上和右视图x上单位矢量。 视锥由6个平面定义。每个平面都由 Cartesian4 对象表示&#xff0c;其中x&#xff0c;y和z分量定义垂直于平面的单位矢量&#xff0c;w分量…...

turbo译码算法MAX, MAX_SCALE and MAX_STAR的比较

在Turbo码的译码算法中&#xff0c;MAX、MAX_SCALE和MAX_STAR是涉及对数似然比&#xff08;LLR&#xff09;计算时&#xff0c;对MAP&#xff08;最大后验概率&#xff09;算法或其变种Log-MAP算法中分支度量计算的几种不同处理方式。下面是对这三种方法的比较&#xff1a; 1.…...

关于HarmonyOS的学习

day31 购物车案例 一、加入购物车 1、点击按钮后&#xff0c;把当前这个列表的数据拿到&#xff0c;应该存储到一个数组里面 --- 数据结构&#xff0c;把数据存储进行数组2、假如已经把所有的数据添加数组完毕&#xff0c;最终应该存储进购物车里面&#xff0c;所谓的购物车说…...

【雅特力AT32】搭建模板工程及GPIO点灯操作

目录 AT32模板工程建立及点灯操作 建立AT32模板工程 AT32点灯操作 LED原理图GPIO寄存器LED源码分析 建立AT32模板工程 从0到编译运行详细搭建保姆教程&#xff1a; 【雅特力AT32】Keil 环境&#xff1a;搭建标准库模板工程、使用 AT-Link、Debug 里选择 CMSIS-DAP调试器 下面做…...

实战千问2大模型第三天——Qwen2-VL-7B(多模态)视频检测和批处理代码测试

画面描述:这个视频中,一位穿着蓝色西装的女性站在室内,背景中可以看到一些装饰品和植物。她双手交叉放在身前,面带微笑,似乎在进行一场演讲或主持活动。她的服装整洁,显得非常专业和自信。 一、简介 阿里通义千问开源新一代视觉语言模型Qwen2-VL。其中,Qwen2-VL-72B在大…...

数据库索引底层数据结构之B+树MySQL中的页索引分类【纯理论干货,面试必备】

目录 1、索引简介 1.1 什么是索引 1.2 使用索引的原因 2、索引中数据结构的设计 —— B树 2.1 哈希 2.2 二叉搜索树 2.3 B树 2.4 最终选择之——B树 2.4.1 B树与B树的对比(面向索引)【面试题】 3、MySQL中的页 3.1 页的使用原因 3.2 页的结构 3.2.1 页文件头和页文件…...

编译QT源码时的configure参数须知

文章目录 一、configure help原文二、configure help机译三、features 执行命令得到configure帮助文件 qtsrc/configure --help一、configure help原文 Usage: configure [options] [-- cmake-options]This is a convenience script for configuring Qt with CMake. Options…...

如何利用人工智能大模型来进行数字化营销?

这是一本关于如何利用人工智能大模型来进行数字化营销并驱动业绩增长的书。人工智能大模型是指那些具有超大规模的参数和数据的人工智能模型&#xff0c;它们能够在各种复杂的任务上表现出惊人的能力。 在本书中&#xff0c;你将学习到如何在电商、广告和用户增长等数字化营销业…...

【MRI基础】回波序列长度-echo train length ETL概念

回波序列长度 回波序列长度 (echo train length, ETL) 是磁共振成像 (MRI) 中的一个重要参数&#xff0c;它对图像采集时间和图像质量有显著影响。ETL 是指在单个激励脉冲之后的 MRI 序列中采集的回波数量。通过增加 ETL&#xff0c;可以在一个重复时间 (TR) 内收集多个回波&a…...

(179)时序收敛--->(29)时序收敛二九

1 目录 (a)FPGA简介 (b)Verilog简介 (c)时钟简介 (d)时序收敛二九 (e)结束 1 FPGA简介 (a)FPGA(Field Programmable Gate Array)是在PAL (可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域…...

[Visual Stuidio 2022使用技巧]2.配置及常用快捷键

使用vs2022开发WPF桌面程序时常用配置及快捷键。 语言&#xff1a;C# IDE&#xff1a;Microsoft Visual Studio Community 2022 框架&#xff1a;WPF&#xff0c;.net 8.0 一、配置 1.1 内联提示 未开启时&#xff1a; 开启后&#xff1a; 开启方法&#xff1a; 工具-选…...

每日奇难怪题(持续更新)

1.以下程序输出结果是() int main() {int a 1, b 2, c 2, t;while (a < b < c) {t a;a b;b t;c--;}printf("%d %d %d", a, b, c); } 解析:a1 b2 c2 a<b 成立 ,等于一个真值1 1<2 执行循环体 t被赋值为1 a被赋值2 b赋值1 c-- c变成1 a<b 不成立…...

江协科技STM32学习- P13 TIM定时器中断

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…...

git github仓库管理

原文链接&#xff1a;git github仓库管理 拉取镜像 github的仓库有两种下载方式,http和ssh,http是对外公开的,可以直接clone,ssh的一般是自己的或内部的仓库,仓库需要配置ssh-key才能使用git clone. 或者直接网页下载 #https git clone https://github.com/git/git.git #ssh…...

FPGA商用级ISP:动态坏点校正(DPCC)的滑窗架构与并行判决实现

【写在前面&#xff1a;为什么要写这个专栏&#xff1f;】在数字图像处理领域&#xff0c;ISP&#xff08;图像信号处理器&#xff09;的算法原理并不罕见&#xff0c;但真正能够支持 4K60fps 实时处理、并经过商用验证的 Verilog 硬核实现思路 却往往秘和封装在黑盒之中。我手…...

效率飙升:用快马生成可复用的wsl环境配置脚本,告别重复劳动

最近在团队协作和更换设备时&#xff0c;经常需要重复配置WSL开发环境&#xff0c;每次都要手动执行一堆命令&#xff0c;不仅耗时还容易遗漏步骤。经过多次实践&#xff0c;我总结出一套用脚本自动化配置的方法&#xff0c;现在通过InsCode(快马)平台就能快速生成可复用的环境…...

OpenClaw开发辅助:Qwen3.5-9B实现日志分析与错误自动修复

OpenClaw开发辅助&#xff1a;Qwen3.5-9B实现日志分析与错误自动修复 1. 为什么需要AI辅助日志分析&#xff1f; 每次凌晨被报警短信吵醒&#xff0c;盯着密密麻麻的日志文件找异常时&#xff0c;我都会想&#xff1a;如果能有个AI助手帮我自动分析日志、定位问题甚至尝试修复…...

从ADC的‘胃口’说起:深入浅出解析电平移位电路中基准源VREF与滤波电容的选型玄学

从ADC的"胃口"说起&#xff1a;深入浅出解析电平移位电路中基准源VREF与滤波电容的选型玄学 在模拟电路设计中&#xff0c;ADC&#xff08;模数转换器&#xff09;就像一位挑剔的美食家&#xff0c;对输入信号的"口味"有着严苛的要求。而电平移位电路则如同…...

告别加班!3个Word神技巧,文档处理快人一步

如影随形地跟着那堆积如山的文档&#xff0c;像学生名单&#xff0c;课程表&#xff0c;教学计划&#xff0c;家长通知等等&#xff0c;这些重复性工作着实耗费了大量精力。事实上&#xff0c;Word当中蕴含着好些能够让你达成事半功倍效果的技巧&#xff0c;一旦将它们掌握住&a…...

轨迹规划实战:用多项式插值+粒子群玩转机械臂运动优化

轨迹规划 路径规划 matlab 353多项式插值 基于改进粒子群算法 时间最优 针对六自由度 四自由度都可以&#xff0c;轨迹规划&#xff0c;多项式插值&#xff0c;更改轨迹点位置就可以搞机器人轨迹规划最头疼的就是既要轨迹丝滑又要时间最短。今天咱们用Matlab整点狠活—…...

Linux initramfs深度解析: 从内核启动到根文件系统的桥梁(3)

接前一篇文章&#xff1a;Linux initramfs深度解析: 从内核启动到根文件系统的桥梁&#xff08;2&#xff09; 设计思想与架构 1. 为什么需要initramfs 在initramfs出现之前&#xff0c;系统启动有一个根本性的问题&#xff1a;内核需要访问根文件系统来加载驱动程序&#xf…...

解锁TikTok电商API:PHP开发者的零门槛接入方案

解锁TikTok电商API&#xff1a;PHP开发者的零门槛接入方案 【免费下载链接】tiktokshop-php Unofficial Tiktok Shop API Client in PHP. Use API version 202309 and later 项目地址: https://gitcode.com/gh_mirrors/ti/tiktokshop-php 跨境电商API对接新选择&#xf…...

3秒获取全网歌词:163MusicLyrics让多平台歌词提取效率提升10倍

3秒获取全网歌词&#xff1a;163MusicLyrics让多平台歌词提取效率提升10倍 【免费下载链接】163MusicLyrics Windows 云音乐歌词获取【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 在数字音乐时代&#xff0c;歌词已成为音乐体验…...

【AI微实验】这就deepseek对音频处理的理解╮(╯▽╰)╭

【手把手】零基础用PythonLibrosa搞定古琴音高识别&#xff0c;附完整代码1. 为什么要用代码“听”古琴&#xff1f;——传统音乐数字化的第一关1.1 从“泠泠七弦上”到“0和1”&#xff1a;音乐信息检索的价值1.2 核心任务拆解&#xff1a;基频&#xff08;F0&#xff09;是什…...