
LeetCode 227. 基本计算器 II — Java 题解题目计算一个字符串表达式的值表达式包含非负整数运算符“”“-”“*”“/”无括号整数除法向零截断输入: “32*2” → 7输入: 3/2 → 1输入: 35 / 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; }}执行过程演示表达式: “32*2-6/4”读取 3 → num3遇 ‘’ → last3, res0, sign‘’读取 2 → num2遇 ‘’ → last326, sign’*’读取 2 → num2遇 ‘-’ → res6 → res6; last-2, sign‘-’读取 6 → num6遇 ‘/’ → last-2… (实际 last 已更新为 -6 后再除)正确推演按代码:res6, 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需加递归或分层面试口诀遇“*”“/” → 马上算遇“”“-” → 先记下遇数字 → 累加构建