Leetcode 224. Basic Calculator

题目

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces.

Example 1:

Input: "1 + 1"
Output: 2

Example 2:

Input: " 2-1 + 2 "
Output: 3

Example 3:

Input: "(1+(4+5+2)-3)+(6+8)"
Output: 23

Note:

  • You may assume that given expression is always valid.

  • Do not use the eval built-in library function.

思路

首先,我们可以先从最基础的两个数相加相减开始思考。

比如我们input string123 - 234, 我们首先需要做的是从string中识别出123234两个operand。我们知道数字为连续的digit characters,因此,我们可以循环地从左到右将123拆成100 + 20 + 3,或234拆成200 + 30 + 4即可得operand。另外,我们需要意识到加法和减法本质上是一样的,123 - 234 = 123 + (-234)。因此如果我们可以利用一个sign为1或-1来表示加减,即operand1 + (sign) * operand2.

然后,我们再从两个数的加减变为多个数的加减(没有括号的情况)。

比如我们的input string12 + 23 - 34。按照我们之前的思路,可得0 + sign1 * operand1 + sign2 * operand2 + sign3 * operand。其中operand1,2,3分别为12, 23, 34, sign1,2,3分别为+1, +1, -1. 我们注意到当数变多之后,我们需要记录的signoperand也越来越多,非常不方便。因此,我们可以在从左到右读input string的时候,同时进行计算,并将结果储存于result中,即12 + 23直接变为35这个result,然后整个式子变成了35 + (- 34),即result += operand * sign

最后,我们再考虑有括号的情况。当我们遇见左括号时,说明我们需要保存当前的resultsign,再重新开启一轮新的括号内的运算;当我们遇见右括号时,我们应该首先计算出括号内结果bracketResult,然后将之前保存的result更新为result += sign * bracketResult

比如1 + 1 - (2 - 5),我们在走完1 + 1之后得到result = 2,和括号前的sign = -1,我们可以先将他们保存至stack,然后重置result, sign,以重新开始括号内运算。当见到)时,我们首先将括号内的运算完成,即bracketResult = 2 - 5 = -3,然后再将bracketResult和之前保存至stack的数和相加或相减。

下图可以让大家更直观的理解这个过程:

Illustration

解答

大家也可结合解答代码中每种情况的注释来理解我们的算法。

Complexity Analysis

  • Time Complexity: O(n). 我们需要遍历String中的所有字母。

  • Space Complexity: O(n). Stack中最多可能装String中的所有数字。

拓展

如果不使用sign来负责加减,我们还能有其他什么办法解决这个问题呢?

总结

这类题型要求我们非常细致对问题进行分情况讨论,且不错过各种细节。一种比较好的思路即为从最简单版的问题想起(比如两个数相加),再逐渐扩充、修改,以满足题目要求。

Last updated

Was this helpful?