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 <= 10num consists of only digits.-231 <= target <= 231 - 1Problem Overview: Given a numeric string num and a target value, insert the operators +, -, or * between digits so the resulting expression evaluates exactly to the target. You cannot reorder digits and you cannot create numbers with leading zeros.
Approach 1: Brute Force Expression Generation (Exponential Time, O(4^n))
The straightforward idea is to generate every possible way to insert operators between digits and then evaluate each expression. For a string of length n, each gap can either place +, -, *, or no operator (concatenate digits). After generating an expression string, evaluate it using a parser or stack-based expression evaluator. This works but becomes expensive because the number of generated expressions grows exponentially and each evaluation costs additional time. Time complexity is roughly O(4^n * n) and space complexity is O(n) for recursion and expression storage.
Approach 2: Recursive Backtracking with Running Evaluation (O(3^n))
The optimized approach builds expressions while evaluating them on the fly using backtracking. Instead of constructing the full expression and evaluating later, track three values during recursion: the current index in the string, the running expression value, and the last operand used. The last operand is required to correctly handle multiplication because * has higher precedence. When you place *, subtract the previous operand from the running total and add the multiplied value.
At each step, extend the current number by taking one or more digits from the string. Skip numbers with leading zeros. Then recursively explore three choices: add (+), subtract (-), or multiply (*) with the current number. This avoids repeated parsing and keeps evaluation constant-time per step. Time complexity is approximately O(3^(n-1)) because each position branches into three operator choices. Space complexity is O(n) for the recursion stack and expression construction.
The algorithm relies heavily on controlled recursion and expression state management, making it a classic string search problem combined with math evaluation rules.
Recommended for interviews: Interviewers expect the recursive backtracking approach with running evaluation. The brute force idea shows you understand the search space, but the optimized method demonstrates control over recursion, operator precedence handling, and pruning invalid states like leading zeros.
This approach involves using a recursive backtracking algorithm to explore all possible combinations of the operators between the digits. The algorithm tries to build expressions from the input string by considering each possible position for inserting an operator. It is essential to keep track of the current value of the expression, the previous operand (to handle multiplication correctly with due precedence), and the current path (the expression string being built).
We also need to ensure that no operand in the expression starts with a zero unless the operand is zero itself to avoid leading zero issues.
The C solution uses a helper function to recursively explore each possibility of operator insertion. It builds expressions by concatenating parts of the input string with operators and maintains an evaluation of the current expression state. The use of sprintf assists in building the expression path.
C++
Java
Python
C#
JavaScript
Time Complexity: O(4^n), where n is the length of the input string 'num'. This accounts for the potential combinatorial explosion in choices of operations between each digit.
Space Complexity: O(n), due to the recursion call stack and the space needed to store the expressions.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Expression Generation | O(4^n * n) | O(n) | Useful for understanding the full search space or quick prototypes when constraints are very small |
| Recursive Backtracking with Running Evaluation | O(3^(n-1)) | O(n) | Best general solution. Avoids expression re-evaluation and handles operator precedence during recursion |
Leetcode questions IRL 🙃 • Alberta Tech • 986,722 views views
Watch 9 more video solutions →Practice Expression Add Operators with our built-in code editor and test cases.
Practice on FleetCode