Given a string num
that contains only digits and an integer target
, return all possibilities to insert the binary operators '+'
, '-'
, and/or '*'
between the digits of num
so that the resultant expression evaluates to the target
value.
Note that operands in the returned expressions should not contain leading zeros.
Example 1:
Input: num = "123", target = 6 Output: ["1*2*3","1+2+3"] Explanation: Both "1*2*3" and "1+2+3" evaluate to 6.
Example 2:
Input: num = "232", target = 8 Output: ["2*3+2","2+3*2"] Explanation: Both "2*3+2" and "2+3*2" evaluate to 8.
Example 3:
Input: num = "3456237490", target = 9191 Output: [] Explanation: There are no expressions that can be created from "3456237490" to evaluate to 9191.
Constraints:
1 <= num.length <= 10
num
consists of only digits.-231 <= target <= 231 - 1
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 brute force approach to adding operators between digits tries every single possible combination of operators. We explore every way to insert '+', '-', or '*' between the digits in the input string and evaluate the resulting expression. We then check if the result equals the target value and save the valid expressions.
Here's how the algorithm would work step-by-step:
def expression_add_operators_brute_force(number_string, target):
result_expressions = []
def explore_expressions(index, current_expression, current_value, previous_operand):
if index == len(number_string):
# Base case: If we've processed all digits, check if the expression evaluates to the target.
if current_value == target:
result_expressions.append(current_expression)
return
for new_index in range(index + 1, len(number_string) + 1):
substring = number_string[index:new_index]
#Avoid leading zero
if len(substring) > 1 and substring[0] == '0':
continue
current_operand = int(substring)
if index == 0:
explore_expressions(new_index, substring, current_operand, current_operand)
else:
#Try adding '+' operator
explore_expressions(new_index, current_expression + '+' + substring, current_value + current_operand, current_operand)
#Try adding '-' operator
explore_expressions(new_index, current_expression + '-' + substring, current_value - current_operand, -current_operand)
# Try adding '*' operator
# Multiplication requires adjusting the previous result.
explore_expressions(new_index, current_expression + '*' + substring, current_value - previous_operand + previous_operand * current_operand, previous_operand * current_operand)
explore_expressions(0, "", 0, 0)
return result_expressions
The problem asks us to find all possible ways to insert +, -, and * operators into a string of digits so that the resulting expression evaluates to a target number. The clever part is to build expressions piece by piece, keeping track of the current result and the last number we added or subtracted, so we can handle the tricky multiplication correctly without recalculating everything from scratch.
Here's how the algorithm would work step-by-step:
def expression_add_operators(numerical_string, target_value):
results = []
def add_operators_recursive(index, current_expression, current_result, previous_operand):
if index == len(numerical_string):
if current_result == target_value:
results.append(current_expression)
return
for j in range(index + 1, len(numerical_string) + 1):
current_substring = numerical_string[index:j]
# Prevent leading zeros
if len(current_substring) > 1 and current_substring[0] == '0':
continue
current_number = int(current_substring)
if index == 0:
add_operators_recursive(j, current_substring, current_number, current_number)
else:
add_operators_recursive(j, current_expression + "+" + current_substring, current_result + current_number, current_number)
add_operators_recursive(j, current_expression + "-" + current_substring, current_result - current_number, current_number)
# Multiplication requires special handling to revert the last operation.
add_operators_recursive(j, current_expression + "*" + current_substring, current_result - previous_operand + previous_operand * current_number, previous_operand * current_number)
add_operators_recursive(0, "", 0, 0)
return results
Case | How to Handle |
---|---|
Empty input string num | Return an empty list as there are no expressions possible. |
Target is a very large or very small number causing potential integer overflow | Use long data type to store intermediate and final results to prevent overflow. |
Leading zeros in the input string num (e.g., '05', '00') | Handle leading zeros to avoid invalid numbers such as '05' by skipping numbers with leading zeros or ensuring they are single '0'. |
Very long input string num (performance concerns) | Consider memoization or other optimization techniques if the string length is extremely large. |
Input string '0' and target 0 | Should return '0' as a valid expression. |
No possible expressions evaluate to the target | Return an empty list when no valid expressions are found. |
Consecutive multiplication and addition/subtraction | Carefully track the last operand's value to correctly apply precedence rules for multiplication. |
Single digit input num and target not matching | Return empty list if the single digit does not match the target value. |