2019. The Score of Students Solving Math Expression
Problem Description
You are given a string s
containing only digits 0-9
, addition symbols '+'
, and multiplication symbols '*'
, representing a valid math expression with single-digit numbers (e.g., 3+5*2
). This expression was given to n
elementary school students who were instructed to evaluate it following these specific rules:
- First, compute all multiplications from left to right
- Then, compute all additions from left to right
For example, for the expression 3+5*2
:
- First, calculate
5*2 = 10
- Then, calculate
3+10 = 13
You are also given an integer array answers
of length n
, containing the answers submitted by the students in no particular order.
Your task is to grade these answers according to the following scoring system:
- 5 points: If the student's answer equals the correct answer (following the proper order of operations)
- 2 points: If the student's answer is incorrect but could be obtained by applying the operators in a different order while still performing correct arithmetic (e.g., calculating
(3+5)*2 = 16
instead of3+(5*2) = 13
) - 0 points: If the student's answer cannot be obtained through any valid interpretation of the expression
The problem asks you to return the total sum of points earned by all students.
The key challenge is to find all possible results that can be obtained by evaluating the expression with different orders of operations (different ways of parenthesizing), while still performing correct arithmetic for each operation. This helps identify which incorrect answers deserve partial credit (2 points) for using valid arithmetic but wrong operation order.
Intuition
The core insight is that we need to find all possible results that can be obtained by evaluating the expression with different parenthesizations. When students apply operators in the wrong order, they're essentially adding parentheses in different places.
For example, with 3+5*2
:
- Correct order:
3+(5*2) = 13
- Wrong order could be:
(3+5)*2 = 16
This naturally leads us to think about interval dynamic programming, where we can break down the expression into smaller subexpressions and combine their results.
The key observation is that any way of evaluating an expression can be viewed as:
- Choosing a position to split the expression into two parts
- Evaluating each part independently
- Combining the results with the operator at the split position
For instance, with digits at positions [i, j]
, we can split at any position k
where i ≤ k < j
, compute all possible results for [i, k]
and [k+1, j]
, then combine them using the operator between positions k
and k+1
.
This recursive structure suggests using dynamic programming where f[i][j]
stores all possible results we can get from evaluating digits from position i
to j
with any parenthesization.
We build up from smaller intervals to larger ones:
- Single digits:
f[i][i]
contains just the digit itself - Larger intervals: For
f[i][j]
, we try all split pointsk
and combine results fromf[i][k]
andf[k+1][j]
By computing all possible results this way, we can identify which student answers deserve partial credit - they're the ones that appear in f[0][m-1]
(all possible results for the entire expression) but aren't the correct answer.
The constraint of limiting results to ≤ 1000
helps keep the set of possible values manageable and prevents the solution from becoming too computationally expensive.
Learn more about Stack, Memoization, Math and Dynamic Programming patterns.
Solution Approach
The solution uses interval dynamic programming to find all possible results from different parenthesizations of the expression.
Step 1: Calculate the Correct Answer
First, we implement a helper function cal(s)
that computes the correct result following the proper order of operations:
- Process multiplications first from left to right
- Then process additions from left to right
def cal(s: str) -> int:
res, pre = 0, int(s[0])
for i in range(1, n, 2):
if s[i] == "*":
pre *= int(s[i + 1])
else:
res += pre
pre = int(s[i + 1])
res += pre
return res
The variable pre
accumulates multiplication results, and when we encounter an addition, we add pre
to res
and start a new accumulation.
Step 2: Initialize the DP Table
We create a 2D DP table f[i][j]
where each cell contains a set of possible results for evaluating digits from position i
to j
:
m = (n + 1) >> 1 # number of digits
f = [[set() for _ in range(m)] for _ in range(m)]
For base cases (single digits), f[i][i]
contains just the digit itself:
for i in range(m):
f[i][i] = {int(s[i << 1])}
Note: s[i << 1]
maps the i-th digit to its position in string s
(digits are at even indices).
Step 3: Fill the DP Table
We iterate through intervals from largest i
to smallest, and for each i
, iterate j
from i
to m-1
:
for i in range(m - 1, -1, -1):
for j in range(i, m):
for k in range(i, j):
for l in f[i][k]:
for r in f[k + 1][j]:
if s[k << 1 | 1] == "+" and l + r <= 1000:
f[i][j].add(l + r)
elif s[k << 1 | 1] == "*" and l * r <= 1000:
f[i][j].add(l * r)
For each interval [i, j]
:
- Try all split points
k
wherei ≤ k < j
- Combine results from
f[i][k]
andf[k+1][j]
- The operator at position
k
is at indexk * 2 + 1
in strings
(operators are at odd indices) - Only add results ≤ 1000 to prevent explosion of possibilities
Step 4: Calculate Final Score
Count occurrences of each answer and assign points:
cnt = Counter(answers) ans = cnt[x] * 5 # 5 points for correct answer for k, v in cnt.items(): if k != x and k in f[0][m - 1]: ans += v << 1 # 2 points for valid but wrong order
- Students with the correct answer
x
get 5 points - Students whose answers appear in
f[0][m-1]
(all possible results) but aren'tx
get 2 points - All other answers get 0 points (implicitly)
The time complexity is O(m^3 * P)
where m
is the number of digits and P
is the maximum number of possible results per interval. The space complexity is O(m^2 * P)
for storing all possible results.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the expression "2+3*4"
with student answers [14, 20, 11, 8]
.
Step 1: Calculate the Correct Answer
Following proper order of operations (multiplication first, then addition):
- First:
3 * 4 = 12
- Then:
2 + 12 = 14
- Correct answer =
14
Step 2: Find All Possible Results Using DP
The expression has 3 digits at positions 0, 2, 4 in the string (digits at even indices). Operators '+' and '*' are at positions 1, 3 (odd indices).
Initialize DP table f[i][j]
for digit indices 0, 1, 2:
f[0][0] = {2}
(just digit '2')f[1][1] = {3}
(just digit '3')f[2][2] = {4}
(just digit '4')
Building up intervals:
For interval [0,1]
(digits "2" and "3" with operator '+'):
- Split at k=0: combine
f[0][0]={2}
andf[1][1]={3}
with '+' - Result:
2 + 3 = 5
f[0][1] = {5}
For interval [1,2]
(digits "3" and "4" with operator '*'):
- Split at k=1: combine
f[1][1]={3}
andf[2][2]={4}
with '*' - Result:
3 * 4 = 12
f[1][2] = {12}
For interval [0,2]
(entire expression):
- Split at k=0: combine
f[0][0]={2}
andf[1][2]={12}
with '+'- Result:
2 + 12 = 14
(this is2+(3*4)
)
- Result:
- Split at k=1: combine
f[0][1]={5}
andf[2][2]={4}
with '*'- Result:
5 * 4 = 20
(this is(2+3)*4
)
- Result:
f[0][2] = {14, 20}
Step 3: Grade Student Answers
All possible valid results: f[0][2] = {14, 20}
Grading each answer:
14
: This is the correct answer → 5 points20
: This appears inf[0][2]
but isn't correct (student calculated(2+3)*4
) → 2 points11
: Not inf[0][2]
(no valid interpretation gives 11) → 0 points8
: Not inf[0][2]
(no valid interpretation gives 8) → 0 points
Total Score: 5 + 2 + 0 + 0 = 7 points
This example shows how the DP approach systematically finds all possible results (14 and 20) by trying different parenthesizations, allowing us to identify which wrong answers deserve partial credit for using valid arithmetic with incorrect operator precedence.
Solution Implementation
1class Solution:
2 def scoreOfStudents(self, s: str, answers: List[int]) -> int:
3 def calculate_correct_answer(expression: str) -> int:
4 """
5 Calculate the correct result of the expression following order of operations.
6 Multiplication is performed before addition.
7 """
8 result = 0
9 current_term = int(expression[0])
10
11 # Process operators and operands pairs
12 for i in range(1, expression_length, 2):
13 operator = expression[i]
14 next_number = int(expression[i + 1])
15
16 if operator == "*":
17 # Multiply with current term
18 current_term *= next_number
19 else: # operator == "+"
20 # Add current term to result and start new term
21 result += current_term
22 current_term = next_number
23
24 # Add the last term
25 result += current_term
26 return result
27
28 expression_length = len(s)
29 correct_answer = calculate_correct_answer(s)
30
31 # Number of operands in the expression
32 num_operands = (expression_length + 1) >> 1 # Equivalent to // 2
33
34 # dp[i][j] stores all possible results for subexpression from operand i to j
35 # considering different evaluation orders (ignoring operator precedence)
36 dp = [[set() for _ in range(num_operands)] for _ in range(num_operands)]
37
38 # Initialize base case: single operands
39 for i in range(num_operands):
40 operand_position = i << 1 # Convert operand index to string position (i * 2)
41 dp[i][i] = {int(s[operand_position])}
42
43 # Fill DP table for all subexpressions
44 for start in range(num_operands - 1, -1, -1):
45 for end in range(start, num_operands):
46 # Try splitting at each possible position
47 for split_point in range(start, end):
48 # Get operator position in string
49 operator_position = split_point << 1 | 1 # (split_point * 2 + 1)
50 operator = s[operator_position]
51
52 # Combine results from left and right subexpressions
53 for left_value in dp[start][split_point]:
54 for right_value in dp[split_point + 1][end]:
55 if operator == "+":
56 new_value = left_value + right_value
57 # Only keep values <= 1000 to avoid overflow
58 if new_value <= 1000:
59 dp[start][end].add(new_value)
60 else: # operator == "*"
61 new_value = left_value * right_value
62 # Only keep values <= 1000 to avoid overflow
63 if new_value <= 1000:
64 dp[start][end].add(new_value)
65
66 # Count occurrences of each answer
67 answer_counts = Counter(answers)
68
69 # Calculate total score
70 total_score = answer_counts[correct_answer] * 5 # 5 points for correct answer
71
72 # Award 2 points for each wrong but possible answer
73 for answer_value, count in answer_counts.items():
74 if answer_value != correct_answer and answer_value in dp[0][num_operands - 1]:
75 total_score += count << 1 # count * 2
76
77 return total_score
78
1class Solution {
2 /**
3 * Calculate the score of students based on their answers to an arithmetic expression.
4 * Students get 5 points for the correct answer, 2 points for a wrong answer that could
5 * result from incorrect order of operations, and 0 points otherwise.
6 *
7 * @param s The arithmetic expression string containing digits and operators (+, *)
8 * @param answers Array of student answers
9 * @return Total score of all students
10 */
11 public int scoreOfStudents(String s, int[] answers) {
12 int expressionLength = s.length();
13 // Calculate the correct answer using proper order of operations
14 int correctAnswer = calculateCorrectAnswer(s);
15
16 // Number of operands in the expression (digits are at even indices)
17 int operandCount = (expressionLength + 1) >> 1;
18
19 // dp[i][j] stores all possible results when evaluating substring from operand i to j
20 Set<Integer>[][] possibleResults = new Set[operandCount][operandCount];
21
22 // Initialize the DP table with empty sets
23 for (int i = 0; i < operandCount; ++i) {
24 for (int j = 0; j < operandCount; ++j) {
25 possibleResults[i][j] = new HashSet<>();
26 }
27 // Base case: single digit evaluation (operands are at even indices in string)
28 possibleResults[i][i].add(s.charAt(i << 1) - '0');
29 }
30
31 // Build up possible results for larger substrings using dynamic programming
32 // Process substrings of increasing length
33 for (int startIdx = operandCount - 1; startIdx >= 0; --startIdx) {
34 for (int endIdx = startIdx; endIdx < operandCount; ++endIdx) {
35 // Try all possible split points
36 for (int splitPoint = startIdx; splitPoint < endIdx; ++splitPoint) {
37 // Get all possible results from left and right substrings
38 for (int leftResult : possibleResults[startIdx][splitPoint]) {
39 for (int rightResult : possibleResults[splitPoint + 1][endIdx]) {
40 // Get the operator between the two parts (operators are at odd indices)
41 char operator = s.charAt(splitPoint << 1 | 1);
42
43 // Apply the operator and add result if within bounds
44 if (operator == '+' && leftResult + rightResult <= 1000) {
45 possibleResults[startIdx][endIdx].add(leftResult + rightResult);
46 } else if (operator == '*' && leftResult * rightResult <= 1000) {
47 possibleResults[startIdx][endIdx].add(leftResult * rightResult);
48 }
49 }
50 }
51 }
52 }
53 }
54
55 // Count frequency of each answer
56 int[] answerFrequency = new int[1001];
57 for (int answer : answers) {
58 ++answerFrequency[answer];
59 }
60
61 // Calculate total score
62 // 5 points for each correct answer
63 int totalScore = 5 * answerFrequency[correctAnswer];
64
65 // 2 points for each wrong but possible answer (from incorrect operation order)
66 for (int possibleAnswer = 0; possibleAnswer <= 1000; ++possibleAnswer) {
67 if (possibleAnswer != correctAnswer &&
68 possibleResults[0][operandCount - 1].contains(possibleAnswer)) {
69 totalScore += 2 * answerFrequency[possibleAnswer];
70 }
71 }
72
73 return totalScore;
74 }
75
76 /**
77 * Calculate the correct result of the expression following proper order of operations.
78 * Multiplication is performed before addition.
79 *
80 * @param s The arithmetic expression string
81 * @return The correct result of the expression
82 */
83 private int calculateCorrectAnswer(String s) {
84 int sum = 0;
85 // Track the current term (which may be a product of multiple numbers)
86 int currentTerm = s.charAt(0) - '0';
87
88 // Process the expression from left to right
89 for (int i = 1; i < s.length(); i += 2) {
90 char operator = s.charAt(i);
91 int nextNumber = s.charAt(i + 1) - '0';
92
93 if (operator == '*') {
94 // Multiplication: extend the current term
95 currentTerm *= nextNumber;
96 } else {
97 // Addition: add the current term to sum and start a new term
98 sum += currentTerm;
99 currentTerm = nextNumber;
100 }
101 }
102
103 // Add the final term
104 sum += currentTerm;
105 return sum;
106 }
107}
108
1class Solution {
2public:
3 int scoreOfStudents(string s, vector<int>& answers) {
4 int n = s.size();
5
6 // Calculate the correct answer using proper order of operations
7 int correctAnswer = calculateCorrectAnswer(s);
8
9 // Number of operands in the expression
10 int numOperands = (n + 1) / 2;
11
12 // dp[i][j] stores all possible results when evaluating s[2*i] to s[2*j]
13 // without following the correct order of operations
14 unordered_set<int> dp[numOperands][numOperands];
15
16 // Base case: single digits
17 for (int i = 0; i < numOperands; ++i) {
18 dp[i][i] = {s[i * 2] - '0'};
19 }
20
21 // Fill dp table for all subranges
22 for (int i = numOperands - 1; i >= 0; --i) {
23 for (int j = i; j < numOperands; ++j) {
24 // Try all possible split points
25 for (int k = i; k < j; ++k) {
26 // Get all possible values from left and right subranges
27 for (int leftValue : dp[i][k]) {
28 for (int rightValue : dp[k + 1][j]) {
29 // Get the operator between the two subranges
30 char op = s[(k * 2) + 1];
31
32 // Calculate result and add to set if within bounds
33 if (op == '+' && leftValue + rightValue <= 1000) {
34 dp[i][j].insert(leftValue + rightValue);
35 } else if (op == '*' && leftValue * rightValue <= 1000) {
36 dp[i][j].insert(leftValue * rightValue);
37 }
38 }
39 }
40 }
41 }
42 }
43
44 // Count frequency of each answer
45 int answerCount[1001] = {0};
46 for (int answer : answers) {
47 ++answerCount[answer];
48 }
49
50 // Calculate total score
51 int totalScore = 5 * answerCount[correctAnswer]; // 5 points for correct answers
52
53 // Add 2 points for each wrong but possible answer
54 for (int value = 0; value <= 1000; ++value) {
55 if (value != correctAnswer && dp[0][numOperands - 1].count(value)) {
56 totalScore += answerCount[value] * 2;
57 }
58 }
59
60 return totalScore;
61 }
62
63private:
64 // Calculate the correct answer following proper order of operations
65 // (multiplication before addition)
66 int calculateCorrectAnswer(string& s) {
67 int result = 0;
68 int currentProduct = s[0] - '0'; // Track current multiplication chain
69
70 for (int i = 1; i < s.size(); i += 2) {
71 int nextNumber = s[i + 1] - '0';
72
73 if (s[i] == '*') {
74 // Continue multiplication chain
75 currentProduct *= nextNumber;
76 } else {
77 // Addition: add previous product to result and start new chain
78 result += currentProduct;
79 currentProduct = nextNumber;
80 }
81 }
82
83 // Add the last multiplication chain
84 result += currentProduct;
85 return result;
86 }
87};
88
1/**
2 * Calculate score of students based on their answers to an arithmetic expression
3 * Students get 5 points for correct answer, 2 points for wrong but possible answer
4 * @param s - The arithmetic expression string with single digits and operators (+, *)
5 * @param answers - Array of student answers
6 * @returns Total score of all students
7 */
8function scoreOfStudents(s: string, answers: number[]): number {
9 const expressionLength = s.length;
10
11 /**
12 * Calculate the correct result of the expression following order of operations
13 * Multiplication is performed before addition
14 * @param expression - The arithmetic expression to evaluate
15 * @returns The correct result of the expression
16 */
17 const calculateCorrectAnswer = (expression: string): number => {
18 let sum = 0;
19 let previousValue = expression.charCodeAt(0) - '0'.charCodeAt(0);
20
21 // Process each operator and operand pair
22 for (let i = 1; i < expression.length; i += 2) {
23 const currentValue = expression.charCodeAt(i + 1) - '0'.charCodeAt(0);
24
25 if (expression[i] === '+') {
26 // For addition, add previous value to sum and update previous
27 sum += previousValue;
28 previousValue = currentValue;
29 } else {
30 // For multiplication, multiply with previous value
31 previousValue *= currentValue;
32 }
33 }
34
35 // Add the last accumulated value
36 sum += previousValue;
37 return sum;
38 };
39
40 // Get the correct answer for the expression
41 const correctAnswer = calculateCorrectAnswer(s);
42
43 // Number of operands in the expression
44 const operandCount = (expressionLength + 1) >> 1;
45
46 // Dynamic programming table: dp[i][j] stores all possible results
47 // for subexpression from operand i to operand j
48 const dpTable: Set<number>[][] = Array(operandCount)
49 .fill(0)
50 .map(() =>
51 Array(operandCount)
52 .fill(0)
53 .map(() => new Set<number>()),
54 );
55
56 // Initialize base case: single operands
57 for (let i = 0; i < operandCount; ++i) {
58 const operandValue = s[i << 1].charCodeAt(0) - '0'.charCodeAt(0);
59 dpTable[i][i].add(operandValue);
60 }
61
62 // Fill DP table for all subexpressions
63 for (let startIdx = operandCount - 1; startIdx >= 0; --startIdx) {
64 for (let endIdx = startIdx; endIdx < operandCount; ++endIdx) {
65 // Try all possible split points
66 for (let splitPoint = startIdx; splitPoint < endIdx; ++splitPoint) {
67 // Get all possible results from left and right subexpressions
68 for (const leftResult of dpTable[startIdx][splitPoint]) {
69 for (const rightResult of dpTable[splitPoint + 1][endIdx]) {
70 // Get the operator between the two subexpressions
71 const operator = s[(splitPoint << 1) + 1];
72
73 if (operator === '+' && leftResult + rightResult <= 1000) {
74 dpTable[startIdx][endIdx].add(leftResult + rightResult);
75 } else if (operator === '*' && leftResult * rightResult <= 1000) {
76 dpTable[startIdx][endIdx].add(leftResult * rightResult);
77 }
78 }
79 }
80 }
81 }
82 }
83
84 // Count frequency of each answer
85 const answerFrequency: number[] = Array(1001).fill(0);
86 for (const answer of answers) {
87 ++answerFrequency[answer];
88 }
89
90 // Calculate total score
91 // Correct answers get 5 points
92 let totalScore = answerFrequency[correctAnswer] * 5;
93
94 // Wrong but possible answers get 2 points
95 for (let possibleAnswer = 0; possibleAnswer <= 1000; ++possibleAnswer) {
96 if (possibleAnswer !== correctAnswer && dpTable[0][operandCount - 1].has(possibleAnswer)) {
97 totalScore += answerFrequency[possibleAnswer] << 1; // Multiply by 2
98 }
99 }
100
101 return totalScore;
102}
103
Time and Space Complexity
The time complexity is O(n^3 × M)
, where n
is the length of string s
and M
is the maximum possible value bound (1000 in this case).
- The outer two loops iterate through all possible substrings:
O(m^2)
wherem = (n+1)/2
is the number of operands, which isO(n^2)
. - For each substring
[i, j]
, we iterate through all possible split pointsk
:O(m)
which isO(n)
. - For each split point, we iterate through all values in
f[i][k]
andf[k+1][j]
. In the worst case, each set can contain up toM
different values. - The nested iteration through two sets gives
O(M^2)
operations for each split point. - However, due to the constraint that we only add values when
l + r <= 1000
orl * r <= 1000
, the actual number of valid combinations is bounded byO(M)
rather thanO(M^2)
. - Total:
O(n^2 × n × M) = O(n^3 × M)
The space complexity is O(n^2 × M)
:
- We have a 2D array
f
of sizem × m
wherem = (n+1)/2
, soO(n^2)
cells. - Each cell contains a set that can have at most
M
elements (bounded by 1000). - The
Counter
for answers takesO(|answers|)
space. - Total:
O(n^2 × M)
Note: The reference answer suggests O(n^3 × M^2)
for time complexity, which would be the case if we didn't have the upper bound constraint (≤ 1000) that effectively limits the number of valid combinations.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Overflow and Memory Issues with Large Intermediate Results
One of the most common pitfalls in this problem is not properly handling the potential explosion of intermediate results in the DP table. Without proper constraints, the sets in the DP table can grow exponentially large, leading to:
- Memory limit exceeded errors
- Time limit exceeded due to processing massive sets
- Integer overflow in calculations
Example of the Problem:
Consider an expression like 9*9*9*9*9
. Without limits:
- First two 9s: {81}
- First three 9s: {729}
- First four 9s: {6561}
- All five 9s: {59049}
But with different parenthesizations, many more intermediate values are possible, and the set sizes can explode.
Solution: The code correctly addresses this by limiting results to 1000:
if operator == "+": new_value = left_value + right_value if new_value <= 1000: # Critical constraint dp[start][end].add(new_value) else: # operator == "*" new_value = left_value * right_value if new_value <= 1000: # Critical constraint dp[start][end].add(new_value)
This constraint is safe because:
- The correct answer is guaranteed to be ≤ 1000 (per problem constraints)
- Any valid alternative interpretation will also be ≤ 1000
- Values > 1000 cannot be valid student answers worth partial credit
2. Incorrect Index Mapping Between Operators and Operands
Another common mistake is incorrectly mapping between:
- Operand indices (0, 1, 2, ...)
- Operator indices (0, 1, 2, ...)
- String positions (operands at even indices, operators at odd indices)
Example of the Problem:
For string "3+5*2"
:
- Operands: position 0 (3), position 2 (5), position 4 (2)
- Operators: position 1 (+), position 3 (*)
Incorrect mapping could lead to:
# Wrong: Using i directly instead of i*2
dp[i][i] = {int(s[i])} # Would get '+' or '*' instead of digit
# Wrong: Incorrect operator position
operator = s[k * 2] # Would get a digit instead of operator
Solution: The code uses bit operations for efficient and correct mapping:
# Operand at index i is at position i*2 in string operand_position = i << 1 # i * 2 # Operator after operand k is at position k*2+1 in string operator_position = split_point << 1 | 1 # split_point * 2 + 1
3. Not Handling the Correct Answer Calculation Properly
A subtle pitfall is incorrectly implementing the standard order of operations in the calculate_correct_answer
function.
Example of the Problem:
For "3+5*2"
, incorrect implementations might:
# Wrong: Evaluating left to right without precedence
result = 3
result = result + 5 # 8
result = result * 2 # 16 (wrong!)
# Wrong: Not accumulating multiplication chains
for i in range(1, n, 2):
if s[i] == "*":
result *= int(s[i + 1]) # Multiplies with running sum
else:
result += int(s[i + 1])
Solution:
The code correctly uses a current_term
variable to accumulate multiplication chains:
result = 0
current_term = int(expression[0])
for i in range(1, expression_length, 2):
if expression[i] == "*":
current_term *= int(expression[i + 1]) # Accumulate multiplications
else: # "+"
result += current_term # Add completed term
current_term = int(expression[i + 1]) # Start new term
result += current_term # Don't forget the last term!
This ensures that 3+5*2
is evaluated as 3+(5*2)=13
, not (3+5)*2=16
.
Which of the following is a min heap?
Recommended Readings
Stack Intro Imagine you have a pile of books on your desk If you want to add a new book you place it on top If you want to read a book you take it from the top And if you simply want to see which book is on the top you
Memoization Prereq Backtracking problems backtracking Memoization is a fancy word for a simple concept so is the case for a lot of things we learn in school It means saving the previous function call result in a dictionary and reading from it when we do the exact same call again
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Want a Structured Path to Master System Design Too? Don’t Miss This!