LeetCode 227. 基本计算器 II — Java 题解
题目
计算一个字符串表达式的值,表达式包含:
- 非负整数
- 运算符
“+”
“-”
“*”
“/”(无括号) - 整数除法向零截断
输入: “3+2*2” → 7
输入: " 3/2 " → 1
输入: " 3+5 / 2 " → 5
核心思路
“*”
“/” 优先级高 → 立即计算
“+”
“-” 优先级低 → 延迟处理
维护 4 个状态变量,单次扫描即可:
变量 含义
“num” 正在读取的当前数字
“last” 上一个数(用于
“*”
“/”)
“sign” 上一个
“+”/
“-” 运算符
“res” 累计结果
核心等式:
“res = res + sign * last”
✅ 解法一:单次扫描(O(1) 空间,推荐)
class Solution {
public int calculate(String s) {
int num = 0, res = 0, last = 0;
char sign = ‘+’;
for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); // 1. 构建数字 if (Character.isDigit(c)) { num = num * 10 + (c - '0'); } // 2. 遇运算符 或 到末尾 → 处理 if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) { if (sign == '+') { res += last; // 结算上一个数 last = num; // 当前数等待后续 } else if (sign == '-') { res += last; last = -num; // 负数 } else if (sign == '*') { last = last * num; // 立即算 } else if (sign == '/') { last = last / num; // 立即算(向零截断) } sign = c; // 记录运算符,作用于下一个数 num = 0; } } return res + last; // 别忘了最后一个 }}
解法二:栈(更直观,O(n) 空间)
class Solution {
public int calculate(String s) {
Deque stack = new ArrayDeque<>();
char sign = ‘+’;
int num = 0;
for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (Character.isDigit(c)) { num = num * 10 + (c - '0'); } if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) { if (sign == '+') stack.push(num); else if (sign == '-') stack.push(-num); else if (sign == '*') stack.push(stack.pop() * num); else if (sign == '/') stack.push(stack.pop() / num); sign = c; num = 0; } } int res = 0; while (!stack.isEmpty()) res += stack.pop(); return res; }}
执行过程演示
表达式: “3+2*2-6/4”
读取 3 → num=3
遇 ‘+’ → last=3, res=0, sign=‘+’
读取 2 → num=2
遇 ‘’ → last=32=6, sign=’*’
读取 2 → num=2
遇 ‘-’ → res+=6 → res=6; last=-2, sign=‘-’
读取 6 → num=6
遇 ‘/’ → last=-2… (实际 last 已更新为 -6 后再除)
正确推演(按代码):
res=6, last 经历: 3 → 6 → -6 → -6/4=-1
返回: res + last = 6 + (-1) = 5 ✅
复杂度
- 时间:
“O(n)” — 只扫描一次 - 空间:
“O(1)”(单次扫描)/
“O(n)”(栈)
⚠️ 易错点
易错点 说明
空格 需跳过
“’ '”
末尾数字 循环结束还要再处理一次
多位数
“num = num*10 + (c-‘0’)”
除法截断 Java
“/” 对正数天然向零;负数如
“-3/2 = -1”
首个无符号 初始化
“sign = ‘+’”
🔑 考点总结
- 运算符优先级:
“*”
“/” >
“+”
“-” - 延迟计算:低优先级暂存,高优先级立即算
- 字符串解析:逐字符构建数字
- 栈 / 状态机:把表达式转成"加法序列"
- 无括号简化:若有括号(LC 224),需加递归或分层
面试口诀:
- 遇
“*”
“/” → 马上算 - 遇
“+”
“-” → 先记下 - 遇数字 → 累加构建