Leetcode刷题224. 基本计算器

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

示例 1:

输入:s = "1 + 1"
输出:2

示例 2:

输入:s = " 2-1 + 2 "
输出:3

示例 3:

输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23

 

提示:

  • 1 <= s.length <= 3 * 105
  • s 由数字、'+''-''('')'、和 ' ' 组成
  • s 表示一个有效的表达式
  • '+' 不能用作一元运算(例如, "+1" 和 "+(2 + 3)" 无效)
  • '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的)
  • 输入中不存在两个连续的操作符
  • 每个数字和运行的计算将适合于一个有符号的 32位 整数

来源:力扣(LeetCode
链接:https://leetcode.cn/problems/basic-calculator/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

感谢labuladong如何拆解复杂问题:实现一个计算器

  1. 定义 Deque<Integer> 来作为栈,存储中间结果。
  2. 定义num 用于记录当前解析的数字,sign 记录前一个运算符的类型。
  3. for 循环遍历字符串中的每个字符。如果是数字,就计算 num;如果是左括号 (,则递归计算括号内的表达式,并将结果赋给 num
  4. 遇到运算符或字符串末尾时,根据 sign作为不同的运算符将num 或其操作后的结果压入栈。
  5. 如果遇到右括号 ),则结束递归调用。
  6. 最后,将栈内所有数字相加,得到最终结果。
class Solution {
    public int calculate(String s) {
		return calculateI(s);
	}

	//方法一:栈
	//遇到括号时,无论多少层括号嵌套,通过calcu函数递归调用自己,都可以将括号中的算式化简成一个数字。
	//换句话说,括号包含的算式,我们直接视为一个数字就行了。
	//时间复杂度O(n),空间复杂度O(n)
	private int calculateI(String s) {
		if (s == null || s.length() == 0) {
			throw new IllegalArgumentException("Input string is null or is empty.");
		}
		return calcu(s);
	}

	private int index = 0;
	private int calcu(String s) {
		Deque<Integer> stack = new ArrayDeque<>();
		int num = 0;
		char sign = '+';
		for (; index < s.length(); index++) {
			//移动到下一个字符
			char c = s.charAt(index);
			if (Character.isDigit(c)) {
				num = num * 10 + (c - '0');
			}
			if (c == '(') {
				//跳过左括号开始递归
				index++;
				num = calcu(s);
			}
			//如果遇到运算符、空格或者到达字符串末尾,根据上一个符号处理数字
			if (!Character.isDigit(c) && c != ' ' || index == s.length() - 1) {
				switch (sign) {
					case '+':
						stack.push(num);
						break;
					case '-':
						stack.push(-num);
						break;
					case '*':
						stack.push(stack.pop() * num);
						break;
					case '/':
						stack.push(stack.pop() / num);
						break;
				}
				sign = c;
				num = 0;
			}
			if (c == ')') {
				//如果为右括号,结束递归(返回后,i指向新生成的数字)
				break;
			}
		}
		int ans = 0;
		while (!stack.isEmpty()) {
			ans += stack.pop();
		}
		return ans;
	}
}
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值