282 这道题用DFS + expression
反正就是塞嘛。
学习了一个很简洁的答案。
用sum表示之前的和,用prev表示上一次的操作数。
每次先把当前的数或加或减到sum上。
把当前的数记为prev,
等到了下一层的时候,很可能这一次是个 *号,那上一次我把prev加上去了,就不合适,要改回来。
这时就把prev从sum里面减去。这样操作比较巧妙,但是比较绕,改来改去的。
我再写一下看能不能不这么干。试了一下确定可以不用改来改去的,可以看我第二个代码 。
强烈推荐第二个代码。
class Solution {
public List addOperators(String num, int target) {
List ans = new ArrayList<>();
helper(num, 0, 0L, 1L, "", target, ans);
return ans;
}
private void helper(String num, int index, long sum, long prev, String path, int target, List ans) {
if (index == num.length()) {
if (sum == (long) target) {
ans.add(path);
}
return;
}
for (int i = index; i < num.length(); i++) {
String seg = num.substring(index, i + 1);
long segNumber = Long.parseLong(seg);
if (i != index && num.charAt(index) == '0') continue;
if (index == 0) {
helper(num, i + 1, segNumber, segNumber, seg, target, ans);
} else {
helper(num, i + 1, sum + segNumber, segNumber, path + "+" + seg, target, ans);
helper(num, i + 1, sum - segNumber, -segNumber, path + "-" + seg, target, ans);
helper(num, i + 1, sum - prev + prev * segNumber, prev * segNumber, path + "*" + seg, target, ans);
}
}
}
}
这是第二个代码, 这个就比较自然, 这里也是用了两个变量,
一个sum表示之前已经清算过的结果的和,比如每次遇到+/- 或者结束,我们都要把之前的和算一算啦,然后加到sum里面去。
如果是*的话,就暂时不要扔到sum里面去, 先放到prev里面。
这个prev表示这个ongoing的session目前的值,他们是相乘的关系,初始化为1(因为左边没有符号默认为正)。在负号后面初始化为 -1;
class Solution {
public List addOperators(String num, int target) {
List ans = new ArrayList<>();
helper(num, 0, 0L, 1L, "", target, ans);
return ans;
}
private void helper(String num, int index, long sum, long prev, String path, int target, List ans) {
// sum stand for the previous sum which has been calculated
//prev stands for the ongoing session.
if (index == num.length()) {
if (sum == (long) target) {
ans.add(path);
}
return;
}
for (int i = index; i < num.length(); i++) {
String seg = num.substring(index, i + 1);
long segNumber = Long.parseLong(seg);
if (i != index && num.charAt(index) == '0') continue;
if (i != num.length() - 1){
//+ - 号必须清算了
helper(num, i + 1, sum + prev * segNumber, 1, path + seg + "+", target, ans);
helper(num, i + 1, sum + prev * segNumber, -1, path + seg + "-", target, ans);
// * 号 不能立马开始清算
helper(num, i + 1, sum, prev * segNumber, path + seg + "*", target, ans);
} else {
//最后也是必须清算了
helper(num, i + 1, sum + prev * segNumber, 1, path + seg, target, ans);
}
}
}
}