这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战
题目描述
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例 1:
输入:s = "3+2*2" 输出:7
示例 2:
输入:s = " 3/2 " 输出:1
示例 3:
输入:s = " 3+5 / 2 " 输出:5
提示:
1 <= s.length <= 3 * 105
s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
s 表示一个 有效表达式
表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
题目数据保证答案是一个 32-bit 整数
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
- 今天的每日一题基本计算器问题,根据题目提示,需要处理+,-*,/四则运算。
- 处理计算器问题,我们一般用栈这种数据结构解决。栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
- 在实际开发中,我们一般使用 Deque 这种结构来处理栈的问题,Deque 双端队列使用起来更加方便。
- 在字符串表达式 s 的处理过程中,我们首先需要区分操作符号和数值,对于 +, - 使用符号进行操作,对于 *, / 计算 *,/ 过后的数值在入栈。 具体实现代码如下:
通过代码
public class DayCode {
public static void main(String[] args) {
String s = "1 + 2 * 3";
int ans = new DayCode().calculate(s);
System.out.println("ans is " + ans);
}
/**
* https://leetcode-cn.com/problems/basic-calculator-ii/
* 时间复杂度O(n)
* 空间复杂度O(n)
* @param s
* @return
*/
public int calculate(String s) {
Deque<Integer> stack = new ArrayDeque<>();
char preSign = '+';
int num = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
if (Character.isDigit(s.charAt(i))) {
num = num * 10 + s.charAt(i) - '0';
}
if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
switch (preSign) {
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
case '*':
stack.push(stack.pop() * num);
break;
case '/':
stack.push(stack.pop() / num);
break;
default:
break;
}
preSign = s.charAt(i);
num = 0;
}
}
int ans = 0;
while (!stack.isEmpty()) {
ans += stack.pop();
}
return ans;
}
}
总结
- 上述代码的时间复杂度是O(n),空间复杂度是O(n)
- 坚持每日一题,加油!