这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
1、题目
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例 1:
1 | ini复制代码输入:s = "3+2*2" |
示例 2:
1 | ini复制代码输入:s = " 3/2 " |
示例 3:
1 | ini复制代码输入:s = " 3+5 / 2 " |
提示:
1 <= s.length <= 3 * 105
s
由整数和算符('+', '-', '*', '/')
组成,中间由一些空格隔开s
表示一个 有效表达式- 表达式中的所有整数都是非负整数,且在范围
[0, 2^31 - 1]
内 - 题目数据保证答案是一个 32-bit 整数
2、思路
(栈,表达式求值) O(n)O(n)O(n)
对于表达式求值这类问题,我们维护两个栈,一个num
栈用来记录数字,一个op
栈用来记录操作符,遍历表达式,遇到操作符时进行数的相应计算。
首先我们定义一个eval()
函数,用于从数字栈num
中弹出两个数字a
和b
,再从操作符栈op
中弹出操作符号,进行计算后将结果数字加入到数字栈num
中。
具体定义如下:
1 | c复制代码void eval() |
然后我们从前往后扫描整个表达式:
- 1、当遇到空格
' '
时,跳过。 - 2、当遇到数字时,则读取一个连续的完整数字,再将其加入到数字栈
num
中。 - 3、当遇到
'+'
,'-'
,'*'
,'/'
运算符时,需要考虑优先级:
+ 如果操作符栈`op`的栈顶元素的优先级比当前遇到的操作符优先级高,则`while`循环进行`eval()`操作,即将数字栈`num`栈顶的两个元素取出来,然后和操作符栈`op`的栈顶操作符进行相应计算,并将计算结果压回数字栈`num`中。
+ 否则,将当前运算符压入操作符栈`op`中。
- 4、扫描完整个表达式后,如果操作符栈
op
中还存在元素,则while
循环进行eval()
操作。 - 5、最终返回数字栈
num
的栈顶元素值。
图示过程:
细节处理:
- 1、由于运算符有优先级,所以设计一个哈希表来存储
'+'
,'-'
,'*'
,'/'
优先级,我们将'+'
和'-'
设为1
级优先级,将'*'
和'/'
设为2
级优先级。 - 2、考虑到表达式
s
的第一个数字可能为负数,因此我们给s
开头添加一个字符0
。
时间复杂度分析: 每个数字和操作进栈出栈一次,所以总的时间复杂度是 O(n)O(n)O(n) 。
3、c++代码
1 | c复制代码class Solution { |
4、java代码
1 | java复制代码class Solution { |
原题链接: 227. 基本计算器 II
本文转载自: 掘金