【LeetCode】 基本计算器 II Java题解

518 阅读1分钟

这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

题目描述

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

整数除法仅保留整数部分。

 

示例 1:

输入:s = "3+2*2" 输出:7

示例 2:

输入:s = " 3/2 " 输出:1

示例 3:

输入:s = " 3+5 / 2 " 输出:5


提示:

1 <= s.length <= 3 * 105
s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
s 表示一个 有效表达式
表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
题目数据保证答案是一个 32-bit 整数

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

思路分析

  • 今天的每日一题基本计算器问题,根据题目提示,需要处理+,-*,/四则运算。
  • 处理计算器问题,我们一般用栈这种数据结构解决。栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
  • 在实际开发中,我们一般使用 Deque 这种结构来处理栈的问题,Deque 双端队列使用起来更加方便。
  • 在字符串表达式 s 的处理过程中,我们首先需要区分操作符号和数值,对于 +, - 使用符号进行操作,对于 *, / 计算 *,/ 过后的数值在入栈。 具体实现代码如下:

通过代码

public class DayCode {
    public static void main(String[] args) {
        String s = "1 + 2 * 3";
        int ans = new DayCode().calculate(s);
        System.out.println("ans is " + ans);
    }

    /**
     * https://leetcode-cn.com/problems/basic-calculator-ii/
     * 时间复杂度O(n)
     * 空间复杂度O(n)
     * @param s
     * @return
     */
    public int calculate(String s) {
        Deque<Integer> stack = new ArrayDeque<>();
        char preSign = '+';
        int num = 0;
        int n = s.length();
        for (int i = 0; i < n; i++) {
            if (Character.isDigit(s.charAt(i))) {
                num = num * 10 + s.charAt(i) - '0';
            }
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
                switch (preSign) {
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    case '*':
                        stack.push(stack.pop() * num);
                        break;
                    case '/':
                        stack.push(stack.pop() / num);
                        break;
                    default:
                        break;
                }
                preSign = s.charAt(i);
                num = 0;
            }
        }

        int ans = 0;
        while (!stack.isEmpty()) {
            ans += stack.pop();
        }
        return ans;
    }
}

总结

  • 上述代码的时间复杂度是O(n),空间复杂度是O(n)
  • 坚持每日一题,加油!