携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情
推荐阅读
大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。
一、题目
1、算法题目
“给定一个字符串表达式,实现一个基本计算器来计算并返回它的值。”
题目链接:
来源:力扣(LeetCode)
2、题目描述
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。
示例 1:
输入: s = "1 + 1"
输出: 2
示例 2:
输入: s = " 2-1 + 2 "
输出: 3
二、解题
1、思路分析
题意要求给定字符串表达式,实现基本计算器来计算并返回它的值。
这段字符串表达式,可能包含的元素有数字和括号、运算符加号和减号。
只有加减法,可以把括号全都展开来写,例如 2 - (1 - 3)展开成 2 - 1 + 3。
也就是,如果当前位置处于括号之内,则:
- 遇到以 - 号开头的括号,此后的符号都要被翻转
- 遇到以 + 号开头的括号,不变
可以考虑维护一个栈ops,栈顶元素存入根据括号所判断的符号sign:
- 如果遇到+号,则更新sign ← ops.top()
- 如果遇到-号,则更新sign ← -ops.top()
每当遇到左括号,则将当前的sign取值压入栈中。
每当遇到右括号,则从栈中弹出一个元素。
2、代码实现
代码参考:
class Solution {
public int calculate(String s) {
Deque<Integer> ops = new LinkedList<Integer>();
ops.push(1);
int sign = 1;
int ret = 0;
int n = s.length();
int i = 0;
while (i < n) {
if (s.charAt(i) == ' ') {
i++;
} else if (s.charAt(i) == '+') {
sign = ops.peek();
i++;
} else if (s.charAt(i) == '-') {
sign = -ops.peek();
i++;
} else if (s.charAt(i) == '(') {
ops.push(sign);
i++;
} else if (s.charAt(i) == ')') {
ops.pop();
i++;
} else {
long num = 0;
while (i < n && Character.isDigit(s.charAt(i))) {
num = num * 10 + s.charAt(i) - '0';
i++;
}
ret += sign * num;
}
}
return ret;
}
}
3、时间复杂度
时间复杂度:O(n)
其中n为字符串s的长度,需要遍历字符串s一次,计算表达式的值。
空间复杂度:O(n)
其中n为字符串s的长度,空间复杂度屈取决于栈的空间,栈中的元素数量不超过n。
三、总结
本题基于栈这一数据结构可以演变出很多种解法。
比如使用双栈,一个栈存放所有的数字,一个栈存放所有数字意外的操作。
然后还是根据符号跟括号判断压入栈的元素。