题目来源:LeetCode227:基本计算器Ⅱ
问题抽象: 设计算法解析并计算包含加减乘除和空格的字符串表达式,需满足以下核心需求:
-
表达式规则:
- 运算符包括
+,-,*,/(无括号); - 操作数为非负整数(可能含空格分隔,无负号);
- 整数除法截断取整(向零取整,如
5/2=2); - 表达式保证合法(以数字开始/结束,运算符不连续)。
- 运算符包括
-
优先级处理:
- 乘除法优先级高于加减法;
- 同级运算符从左到右计算(如
3-2+1先算减后算加)。
-
核心计算策略:
- 栈存储中间结果:
- 加减法:将操作数带符号压栈(
+num或-num); - 乘除法:立即与栈顶元素计算并更新栈顶(实现优先级);
- 加减法:将操作数带符号压栈(
- 符号延迟更新:
- 遍历时记录当前运算符,在遇到下一运算符时触发前序计算。
- 栈存储中间结果:
-
复杂度约束:
- 时间复杂度 O(n)(单次遍历字符串,
n为长度); - 空间复杂度 O(m)(栈空间,
m为操作数数量,最坏O(n))。
- 时间复杂度 O(n)(单次遍历字符串,
-
边界处理:
- 空格跳过(
s.replaceAll(" ","")非最优解,需遍历时跳过); - 多位数解析(连续数字字符转为整数);
- 除法截断:
7/3=2(非四舍五入); - 整数范围:
[0, 2³¹-1](无需显式处理溢出)。
- 空格跳过(
输入:字符串 s(长度 ∈ [1, 3×10⁴],如 " 3+5 / 2 ")
输出:整数(计算结果,如 5)
解题思路
为了高效解决基本计算器问题,我们采用一次遍历字符串的方法,同时处理运算符优先级(乘除优先于加减)。核心思路是:
- 遍历字符串:逐个字符处理,跳过空格,累计数字。
- 处理运算符:使用变量
preOp记录上一个运算符,preNum记录当前乘除链的结果,cur记录当前数字。 - 遇到新运算符或结尾时:
- 根据
preOp更新preNum:'+':preNum = cur'-':preNum = -cur'*'或'/':立即计算preNum与cur的乘除结果。
- 若当前运算符是
'+'、'-'或到达结尾,将preNum累加到最终结果res并重置preNum为 0。
- 根据
- 更新运算符:记录当前运算符用于下一次计算。
- 结尾处理:遍历结束时,将最后的
preNum累加到结果。
代码实现(Java版)🔥点击下载源码
class Solution {
public int calculate(String s) {
int res = 0; // 最终结果
int preNum = 0; // 当前乘除链的结果
int cur = 0; // 当前累计的数字
char preOp = '+'; // 上一个运算符,初始为'+'
int n = s.length();
for (int i = 0; i <= n; i++) {
char c = i < n ? s.charAt(i) : ' '; // 末尾用空格标记
if (c == ' ' && i != n) continue; // 跳过非末尾空格
if (c >= '0' && c <= '9') {
cur = cur * 10 + (c - '0'); // 累计数字
} else {
// 根据上一个运算符更新preNum
switch (preOp) {
case '+':
preNum = cur;
break;
case '-':
preNum = -cur;
break;
case '*':
preNum = preNum * cur;
break;
case '/':
preNum = preNum / cur;
break;
}
// 加减或结尾:累加preNum到res,并重置preNum
if (c == '+' || c == '-' || i == n) {
res += preNum;
preNum = 0;
}
// 更新运算符(非末尾)
if (i < n) {
preOp = c;
}
cur = 0; // 重置当前数字
}
}
return res;
}
}
代码说明
- 变量说明:
res:累加最终结果。preNum:记录当前乘除链的中间结果(如3*2/2的中间结果)。cur:遍历中累计的当前数字。preOp:记录上一个运算符,用于决定如何更新preNum。
- 核心逻辑:
- 数字处理:遇到数字字符时,累加到
cur。 - 运算符/结尾处理:
- 根据
preOp更新preNum(乘除立即计算,加减暂存带符号值)。 - 若当前运算符是加减或到达结尾,将
preNum累加到res并重置preNum。 - 更新
preOp为当前运算符。
- 根据
- 数字处理:遇到数字字符时,累加到
- 空格处理:非末尾空格直接跳过,不影响数字累计和运算符处理。
- 高效性:一次遍历完成计算,空间复杂度 O(1),时间复杂度 O(n)。
提交详情(执行用时、内存消耗)

7513

被折叠的 条评论
为什么被折叠?



