forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 1
/
the-score-of-students-solving-math-expression.py
70 lines (65 loc) · 2.58 KB
/
the-score-of-students-solving-math-expression.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Time: O(n^3 * a^2)
# Space: O(n^2)
class Solution(object):
def scoreOfStudents(self, s, answers):
"""
:type s: str
:type answers: List[int]
:rtype: int
"""
MAX_ANS = 1000
n = (len(s)+1)//2
dp = [[set() for _ in xrange(n)] for _ in xrange(n)]
for i in xrange(n):
dp[i][i].add(int(s[i*2]))
for l in xrange(1, n):
for left in xrange(n-l):
right = left+l
for k in xrange(left, right):
if s[2*k+1] == '+':
dp[left][right].update((x+y for x in dp[left][k] for y in dp[k+1][right] if x+y <= MAX_ANS))
else:
dp[left][right].update((x*y for x in dp[left][k] for y in dp[k+1][right] if x*y <= MAX_ANS))
target = eval(s)
return sum(5 if ans == target else 2 if ans in dp[0][-1] else 0 for ans in answers)
# Time: O(n^3 * a^2)
# Space: O(n^2)
class Solution2(object):
def scoreOfStudents(self, s, answers):
"""
:type s: str
:type answers: List[int]
:rtype: int
"""
MAX_ANS = 1000
def evaluate(s):
def compute(operands, operators):
right, left = operands.pop(), operands.pop()
operands.append(ops[operators.pop()](left, right))
ops = {'+':operator.add, '*':operator.mul}
precedence = {'+':0, '*':1}
operands, operators, operand = [], [], 0
for c in s:
if c.isdigit():
operands.append(int(c))
else:
while operators and precedence[operators[-1]] >= precedence[c]:
compute(operands, operators)
operators.append(c)
while operators:
compute(operands, operators)
return operands[-1]
n = (len(s)+1)//2
dp = [[set() for _ in xrange(n)] for _ in xrange(n)]
for i in xrange(n):
dp[i][i].add(int(s[i*2]))
for l in xrange(1, n):
for left in xrange(n-l):
right = left+l
for k in xrange(left, right):
if s[2*k+1] == '+':
dp[left][right].update((x+y for x in dp[left][k] for y in dp[k+1][right] if x+y <= MAX_ANS))
else:
dp[left][right].update((x*y for x in dp[left][k] for y in dp[k+1][right] if x*y <= MAX_ANS))
target = evaluate(s)
return sum(5 if ans == target else 2 if ans in dp[0][-1] else 0 for ans in answers)