LeetCode题练习与总结:基本计算器--224

245 篇文章 0 订阅
44 篇文章 0 订阅

一、题目描述

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

二、解题思路

  • 使用一个栈来存储操作数和一个变量来存储当前的计算结果。
  • 使用一个变量 sign 来记录当前的符号,初始化为 +
  • 遍历字符串,对于每个字符:
    • 如果是数字,则更新当前数字(可能有多位)。
    • 如果是符号(+ 或 -)或者遇到括号,则将之前的数字(如果有)和符号计算进当前结果。
    • 如果是左括号 (,将当前结果和符号压入栈中,并重置为开始新的子表达式的计算。
    • 如果是右括号 ),则计算当前子表达式的结果,并从栈中弹出之前的符号和结果,继续计算。
  • 在遍历结束后,将最后的数字(如果有)加到结果中。

三、具体代码

import java.util.Stack;

class Solution {
    public int calculate(String s) {
        Stack<Integer> stack = new Stack<>();
        int result = 0;
        int number = 0;
        int sign = 1; // 1 for '+', -1 for '-'
        
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                number = number * 10 + (c - '0');
            } else if (c == '+') {
                result += sign * number;
                sign = 1;
                number = 0;
            } else if (c == '-') {
                result += sign * number;
                sign = -1;
                number = 0;
            } else if (c == '(') {
                // Push the result and sign on to the stack, then reset them
                stack.push(result);
                stack.push(sign);
                // Reset the result and sign for the value in the parenthesis
                result = 0;
                sign = 1;
            } else if (c == ')') {
                // First number * sign
                result += sign * number;
                number = 0;
                // Add the result from the parenthesis to the last result
                result *= stack.pop(); // This should be the sign before the parenthesis
                result += stack.pop(); // This should be the result calculated before the parenthesis
            }
        }
        if (number != 0) {
            result += sign * number;
        }
        return result;
    }
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 我们需要遍历字符串 s 一次,其长度为 n
  • 在遍历过程中,对于每个字符,我们执行常数时间的操作,如判断字符类型、计算数字、更新结果等。
  • 因此,整个算法的时间复杂度为 O(n),其中 n 是字符串 s 的长度。
2. 空间复杂度
  • 我们使用了一个栈 stack 来存储中间结果和符号。
  • 在最坏的情况下,如果表达式 s 是一个嵌套很深的括号表达式,栈的大小可能会达到 n(即字符串的长度)。
  • 因此,空间复杂度为 O(n),其中 n 是字符串 s 的长度。

五、总结知识点

  • 基本数据类型

    • int:用于表示整数。
    • char:用于表示单个字符。
  • 类和对象

    • class Solution:定义一个名为 Solution 的类。
    • new Stack<Integer>():创建 Stack 类的实例,用于实现栈数据结构。
  • 循环结构

    • for 循环:用于遍历字符串中的每个字符。
  • 条件判断

    • if-else if-else:用于根据不同的字符类型执行不同的操作。
  • 字符串处理

    • String.length():获取字符串的长度。
    • String.charAt(int index):获取字符串中指定位置的字符。
  • 字符操作

    • Character.isDigit(char c):判断字符是否为数字。
  • 数学运算

    • 算术运算:加法(+)、乘法(*)、减法(-)。
    • 模运算:c - '0',用于将字符数字转换为整数。
  • 栈操作

    • Stack.push(E item):将元素压入栈顶。
    • Stack.pop():移除栈顶元素并返回。
  • 逻辑处理

    • 符号处理:根据符号 + 或 - 更新计算结果。
    • 括号处理:使用栈来处理嵌套的括号表达式。
  • 算法思想

    • 使用栈来处理表达式中括号和运算符的优先级。
    • 使用变量来存储中间计算结果和当前的操作符。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直学习永不止步

谢谢您的鼓励,我会再接再厉的!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值