Expression Add Operators
Master this topic with zero to advance depth.
Expression Add Operators
Precedence and Multiplication
Adding + and - is straightforward: just add or subtract the current value. However, multiplication (*) has higher precedence. If we have 1 + 2 * 3, we cannot simply compute (1 + 2) * 3.
The Trick: Tracking Previous Operand
To handle prev + current * next, we need to subtract current and add current * next.
Formula: NewTotal = (OldTotal - prevOperand) + (prevOperand * currentValue).
Corner Cases
- Leading Zeros: A number like
"05"is invalid unless it's just"0". - Overflow: Since the target and intermediate values can exceed , use
long(64-bit integers).
Given a string num containing 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.
Examples
Level I: Basic Backtracking with Post-Evaluation
Intuition
Insert every possible operator between digits to generate all possible expressions, then evaluate each one.
Generate expressions by recursion. For each string of length , there are combinations. This is very slow due to the evaluation step.
Detailed Dry Run
num="12", target=3.
- Try "1+2" -> eval(3) == 3 -> SUCCESS.
- Try "1-2" -> eval(-1) != 3.
- Try "1*2" -> eval(2) != 3.
Level II: Optimized Backtracking (Running Value)
Intuition
Calculate the expression value on the fly to avoid explicit evaluation. Handle multiplication by tracking the previous added value.
Use dfs(index, path, currentVal, prevOperand). If we add *, the new value is (currentVal - prevOperand) + (prevOperand * now).
Detailed Dry Run
num="123", target=6
- Pick "1": val=1, prev=1.
- Pick "2" with "+": val=1+2=3, prev=2.
- Pick "3" with "+": val=3+3=6, prev=3. SUCCESS.
- Pick "2" with "": val=(1-1)+(12)=2, prev=2.
- Pick "3" with "": val=(2-2)+(23)=6, prev=6. SUCCESS.
Level III: Memory-Optimized Backtracking
Intuition
Instead of building string paths and then converting them, use a char[] or byte[] to build the path directly, avoiding string concatenations which are expensive.
Pass a char[] (or byte[] in Go) to the recursive function. When adding an operator or digit, update the array and its current length. Backtrack by resetting the length.
Detailed Dry Run
num="123", target=6
- path=['1'], len=1. dfs(1, 1, 1, path)
- path=['1','+','2'], len=3. dfs(2, 3, 2, path)
- path=['1','+','2','+','3'], len=5. dfs(3, 6, 3, path). Target hit. Add "1+2+3" to res.
- Backtrack: path=['1','+','2'], len=3. Try '*'.
- path=['1','+','2','','3'], len=5. dfs(3, 1+2-2+23=7, 2*3=6, path). Target not hit.
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.