class Solution:
def addOperators(self, num: str, target: int):
res = []
def dfs(index, path, value, prev):
if index == len(num):
if value == target:
res.append(path)
return
for i in range(index + 1, len(num) + 1):
tmp = num[index:i]
if len(tmp) > 1 and tmp[0] == '0':
break
n = int(tmp)
if index == 0:
dfs(i, tmp, n, n)
else:
dfs(i, path + '+' + tmp, value + n, n)
dfs(i, path + '-' + tmp, value - n, -n)
dfs(i, path + '*' + tmp, value - prev + prev * n, prev * n)
dfs(0, '', 0, 0)
return res
class Solution {
public:
vector<string> addOperators(string num, int target) {
vector<string> res;
function<void(int, string, long, long)> dfs = [&](int pos, string path, long value, long prev) {
if (pos == num.size()) {
if (value == target) res.push_back(path);
return;
}
for (int i = pos + 1; i <= num.size(); ++i) {
string tmp = num.substr(pos, i - pos);
if (tmp.size() > 1 && tmp[0] == '0') break;
long n = stol(tmp);
if (pos == 0) {
dfs(i, tmp, n, n);
} else {
dfs(i, path + "+" + tmp, value + n, n);
dfs(i, path + "-" + tmp, value - n, -n);
dfs(i, path + "*" + tmp, value - prev + prev * n, prev * n);
}
}
};
dfs(0, "", 0, 0);
return res;
}
};
class Solution {
public List<String> addOperators(String num, int target) {
List<String> res = new ArrayList<>();
dfs(num, target, 0, "", 0, 0, res);
return res;
}
private void dfs(String num, int target, int pos, String path, long value, long prev, List<String> res) {
if (pos == num.length()) {
if (value == target) res.add(path);
return;
}
for (int i = pos + 1; i <= num.length(); i++) {
String tmp = num.substring(pos, i);
if (tmp.length() > 1 && tmp.charAt(0) == '0') break;
long n = Long.parseLong(tmp);
if (pos == 0) {
dfs(num, target, i, tmp, n, n, res);
} else {
dfs(num, target, i, path + "+" + tmp, value + n, n, res);
dfs(num, target, i, path + "-" + tmp, value - n, -n, res);
dfs(num, target, i, path + "*" + tmp, value - prev + prev * n, prev * n, res);
}
}
}
}
var addOperators = function(num, target) {
let res = [];
function dfs(index, path, value, prev) {
if (index === num.length) {
if (value === target) res.push(path);
return;
}
for (let i = index + 1; i <= num.length; i++) {
let tmp = num.slice(index, i);
if (tmp.length > 1 && tmp[0] === '0') break;
let n = Number(tmp);
if (index === 0) {
dfs(i, tmp, n, n);
} else {
dfs(i, path + '+' + tmp, value + n, n);
dfs(i, path + '-' + tmp, value - n, -n);
dfs(i, path + '*' + tmp, value - prev + prev * n, prev * n);
}
}
}
dfs(0, '', 0, 0);
return res;
};
num
consisting of only digits and an integer target
. Your task is to add the binary operators '+'
, '-'
, or '*'
between the digits in num
(not necessarily between every digit) so that the resulting mathematical expression evaluates to target
. Return all such possible expressions in any order.
num
must be used in the original order and exactly once.target
should be returned.target
. However, brute-force evaluation can quickly become infeasible as the number of digits increases, since the number of possible combinations grows exponentially.
A key insight is that we need to generate all valid expressions, but also evaluate them efficiently and correctly, especially given operator precedence (multiplication before addition and subtraction). To avoid redundant computation, we should build expressions incrementally and keep track of the running total, as well as the most recent operand (to handle multiplication precedence).
We also need to handle leading zeros, ensuring we do not generate numbers like "05" or "00" as valid operands.
Finally, recursion (backtracking) is a natural fit for this problem, as we can try each operator at each position, backtrack, and try the next possibility.
num
, the expression built so far (path
), the computed value so far (value
), and the value of the last operand (prev
).
target
. If so, add the current expression to the result list.
num = "123"
and target = 6
.
["1+2+3", "1*2*3"]
.
O(4^{n-1})
possible expressions for n
digits (since there are 3 operators and the "no operator" choice). Evaluating each expression naively can take up to O(n)
time.
O(n)
deep, and the result list can contain up to O(4^{n-1})
expressions in the worst case.