Given a string expression of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. You may return the answer in any order.
The test cases are generated such that the output values fit in a 32-bit integer and the number of different results does not exceed 104.
Example 1:
Input: expression = "2-1-1" Output: [0,2] Explanation: ((2-1)-1) = 0 (2-(1-1)) = 2
Example 2:
Input: expression = "2*3-4*5" Output: [-34,-14,-10,-10,10] Explanation: (2*(3-(4*5))) = -34 ((2*3)-(4*5)) = -14 ((2*(3-4))*5) = -10 (2*((3-4)*5)) = -10 (((2*3)-4)*5) = 10
Constraints:
1 <= expression.length <= 20expression consists of digits and the operator '+', '-', and '*'.[0, 99].'-' or '+' denoting the sign.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The problem asks us to find all the possible results of an arithmetic expression by grouping parts of it with parentheses in different ways. The brute force strategy is simple: we try every single possible way to add parentheses to the expression.
Here's how the algorithm would work step-by-step:
def different_ways_to_add_parentheses(expression):
# If the expression is just a number, return it as an integer.
if expression.isdigit():
return [int(expression)]
results = []
for index, character in enumerate(expression):
# Find each operator in the expression.
if character in ['+', '-', '*']:
# Recursively compute results for left and right subexpressions.
left_results = different_ways_to_add_parentheses(expression[:index])
right_results = different_ways_to_add_parentheses(expression[index+1:])
# Combine the results from the left and right.
for left_result in left_results:
for right_result in right_results:
if character == '+':
results.append(left_result + right_result)
elif character == '-':
results.append(left_result - right_result)
elif character == '*':
results.append(left_result * right_result)
return resultsThe goal is to explore every possible way to insert parentheses into an expression and calculate the result. We'll use a method where we break down the problem into smaller, self-similar subproblems and combine their results to find all final answers.
Here's how the algorithm would work step-by-step:
def different_ways_to_add_parentheses(input_expression):
# If the input is a number, return it as a single-element list.
if input_expression.isdigit():
return [int(input_expression)]
results = []
for index, character in enumerate(input_expression):
if character in ['+', '-', '*']:
# Split the expression into two sub-expressions
left_sub_expression = input_expression[:index]
right_sub_expression = input_expression[index + 1:]
# Recursively calculate results for sub-expressions
left_results = different_ways_to_add_parentheses(left_sub_expression)
right_results = different_ways_to_add_parentheses(right_sub_expression)
# Combine results from left and right sub-expressions
for left_result in left_results:
for right_result in right_results:
if character == '+':
results.append(left_result + right_result)
elif character == '-':
results.append(left_result - right_result)
else:
results.append(left_result * right_result)
return results| Case | How to Handle |
|---|---|
| Null or empty input string | Return an empty list if the input string is null or empty, as there are no expressions to evaluate. |
| Input string containing only a single number | Return a list containing the single number as an integer, since there are no operations to perform. |
| Input string with only one operator and two numbers (e.g., '1+2') | Evaluate the simple expression directly and return a list containing the single result. |
| Input string with leading/trailing whitespace | Trim the input string to remove any leading or trailing whitespace before processing to avoid parsing errors. |
| Input string with very large numbers that could lead to integer overflow | Use long integer data type to store intermediate results and final answers to prevent integer overflow, and check for potential overflows during calculations. |
| Input string with a large number of operators and operands (potential stack overflow with naive recursion) | Implement memoization to store intermediate results and avoid redundant calculations, improving efficiency and reducing stack depth. |
| Input with negative numbers or negative intermediate results | The parsing and evaluation logic should correctly handle negative numbers and intermediate results during calculations. |
| Input containing only multiplication with zero e.g. '0*0*0' | The solution needs to handle multiplication with zero correctly, returning 0 as the only possible result. |