Similar to LC772 Basic Calculator III
# Definition for a binary tree node.
# class Node(object):
# def __init__(self, val=" ", left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def expTree(self, s: str) -> 'Node':
"""
main idea: [two stacks] use two stack to store operators and vals seperately
rules1: when encountering '+-', if top of op stack is '+-*/', we merge two nodes in nums stack using top op in ops stack
rules2: when encountering '*/', if we can't compute previous '+-' due to priority limit. we can merge top two nodes off nums stack only when we see '*/' in ops stack
rules3: when encountering ')', we merge the nodes until top of ops stack is '('
"""
ops,vals = [],[] # ops store +-*/ and ()
def mock_compute():
op = ops.pop()
r = vals.pop()
l = vals.pop()
vals.append(Node(op,l,r))
for c in s:
if c.isdigit():
vals.append(Node(val = c))
elif c in ['-','+']:
while ops and ops[-1] in ['+','-','*','/']: # note here is while not if
mock_compute()
ops.append(c)
elif c in ['*','/']:
while ops and ops[-1] in ['*','/']: # note here is while not if
mock_compute()
ops.append(c)
elif c == '(':
ops.append(c)
elif c ==')':
while ops[-1] != '(':
mock_compute()
ops.pop() # remove '('
while ops:
mock_compute()
return vals[0]
############# shorter version
class Solution:
def expTree(self, s: str) -> 'Node':
ops,vals = [],[]
def mock_compute():
op = ops.pop()
r = vals.pop()
l = vals.pop()
vals.append(Node(op,l,r))
# return True if priority(op1) >= priority(op2) = > op1 in [+-*/] or op2 in [+,-]
def compare(op1,op2)->bool:
if op1 in ['(',')']:
return False
return op1 in ['*','/'] or op2 in ['+','-']
for c in s:
if c.isdigit():
vals.append(Node(val = c))
elif c == '(':
ops.append(c)
elif c ==')':
while ops[-1] != '(':
mock_compute()
ops.pop()
else: # c in [+-*/]
while ops and compare(ops[-1],c):
mock_compute()
ops.append(c)
while ops:
mock_compute()
return vals[-1]