【做题也是一场游戏】面试题 16.26. 计算器

246 阅读1分钟

题目地址

leetcode-cn.com/problems/ca…

题目描述

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  。 整数除法仅保留整数部分。

示例 1:

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

示例 2:

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

示例 3:

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

说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval

题解

题目保证了表达式是合法的,那么这个表达式的第一个字符我们可以想象成 +

我们将每个运算符之间的数字当做一个单元,但是由于乘除的优先级高于加减,那么我们将乘除的结果当做一个单元,而减法可以看成是加上一个负数,那么这个表达式就被分解成了多个加号分隔的部分,只要将这些部分求和即可。

剩下的就是怎么存储这些单元,由于在进行乘除的时候,需要用到前面的数并且乘除可能是连续的,那么需要借助栈来获取前面的述数字。

class Solution {
    public int calculate(String s) {

        char[] array = s.toCharArray();

        Deque<Integer> stack = new LinkedList<>();

        int i = 0;
        while (i < array.length) {
            if (array[i] == ' ') {
                i++;
                continue;
            }
            int j = i;
            if (array[j] == '+' || array[j] == '-' || array[j] == '*' || array[j] == '/') {
                j++;
                while (j < array.length) {
                    if (array[j] == ' ') {
                        j++;
                        continue;
                    } else {
                        break;
                    }
                }
            }
            int number = 0;
            while (j < array.length) {
                if (array[j] >= '0' && array[j] <= '9') {
                    number = number * 10 + (array[j] - '0');
                    j++;
                } else {
                    break;
                }
            }
            if (array[i] == '+') {
                stack.offerLast(number);
            } else if (array[i] == '-') {
                stack.offerLast(-number);
            } else if (array[i] == '*') {
                stack.offerLast(stack.pollLast() * number);
            } else if (array[i] == '/') {
                stack.offerLast(stack.pollLast() / number);
            } else {
                stack.offerLast(number);
            }
            i = j;
        }
        int result = 0;
        while (!stack.isEmpty()) {
            result += stack.pollLast();
        }

        return result;
    }
}

复杂度分析

  • 时间复杂度: O(n)O(n)
  • 空间复杂度: O(n)O(n), 实际上是不需要 n 的