此题准确的说是一个括号匹配问题,我们可以从里到外拆解问题。每遇到一个后括号,就把前面的提出来解决,这样就没有内层了,可以用栈实现,代码如下:
class Solution:
def calculate(self, s: str) -> int:
if len(s) == 0: return 0
stack = []
def process():
l = []
last, tmp, pos = 's', 0, 0
while stack:
c0 = stack.pop()
if type(c0) == type('2') and c0.isdigit(): c0 = int(c0)
if c0 == '(': break
elif type(c0) == type(2):
tmp += 10**pos*c0
pos += 1
else:
l.append(tmp)
l.append(c0)
tmp, pos = 0, 0
l.append(tmp)
num = 0
sign = 1 # 1为加,-1为减
for c1 in reversed(l):
if type(c1) == type(2):
num += sign*int(c1)
elif c1 == '-':
sign = -1
elif c1 == '+':
sign = 1
stack.append(num)
for i, c in enumerate(s):
if c == ')':
process()
elif c != ' ':
stack.append(c)
process()
return stack[0]
可以看到,中间有一步是很浪费时间的,就是把元素取出来,又放入新的列表,又取出来。如果能省去这一过程,程序会快很多。
class Solution:
def calculate(self, s: str) -> int:
if len(s) == 0: return 0
stack = []
def process():
num = 0
last, tmp, pos = 's', 0, 0
while stack:
c0 = stack.pop()
if type(c0) == type('2') and c0.isdigit(): c0 = int(c0)
if c0 == '(': break
elif type(c0) == type(2):
tmp += 10**pos*c0
pos += 1
else:
if c0 == '-': tmp = -tmp
num += tmp
tmp, pos = 0, 0
stack.append(num+tmp)
for i, c in enumerate(s):
if c == ')':
process()
elif c != ' ':
stack.append(c)
process()
return stack[0]
其实这样还是很慢,所以我们必须找到更透彻的解法:即题解解法,所有数字没有变,变的只是符号,我们只需要用一个栈存符号即可。。这样就会很快。
此外,从前往后累加一个数也挺简单的,一直让前面乘10即可。
class Solution:
def calculate(self, s: str) -> int:
if len(s) == 0: return 0
stack = [1]
ret, sign = 0, 1
tmp = 0
for i, c in enumerate(s):
if c.isdigit():
tmp = tmp*10 + int(c)
else:
ret += tmp*sign
tmp = 0
if c == '+':
sign = stack[-1]
elif c == '-':
sign = -stack[-1]
elif c == '(':
stack.append(sign)
elif c == ')':
stack.pop()
return ret+tmp*sign