1. 题目
2. 思路
(1) 迭代
(2) 回溯法
3. 代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.addOperators("1000000009", 9));
}
}
class Solution {
private List<Map<String, Long>> map = new ArrayList<>();
public List<String> addOperators(String num, int target) {
map.add(new HashMap<String, Long>() {{
put(String.valueOf(num.charAt(0)), Long.valueOf(String.valueOf(num.charAt(0))));
}});
for (int i = 1; i < num.length(); i++) {
String ch = String.valueOf(num.charAt(i));
long val = Long.valueOf(ch);
Map<String, Long> pre = map.get(i - 1);
Map<String, Long> cur = new HashMap<>();
for (Map.Entry<String, Long> entry : pre.entrySet()) {
String s = entry.getKey();
long v = entry.getValue();
String s1 = s + "+" + ch;
long v1 = v + val;
cur.put(s1, v1);
String s2 = s + "-" + ch;
long v2 = v - val;
cur.put(s2, v2);
String s3 = s + "*" + ch;
long v3 = multiple(s3);
cur.put(s3, v3);
if (num.charAt(i - 1) != '0') {
String s4 = s + ch;
long v4 = Blank(s4);
cur.put(s4, v4);
}
}
map.add(cur);
}
List<String> res = new ArrayList<>();
for (Map.Entry<String, Long> entry : map.get(map.size() - 1).entrySet()) {
if (entry.getValue() == target) {
res.add(entry.getKey());
}
}
return res;
}
private long multiple(String num) {
int mid = num.length() - 1;
while (mid >= 0) {
if (num.charAt(mid) == '+' || num.charAt(mid) == '-') {
break;
}
mid--;
}
int preDigitCount = 0;
for (int i = 0; i < mid; i++) {
if (Character.isDigit(num.charAt(i))) {
preDigitCount++;
}
}
long preRes = 0;
if (preDigitCount > 0) {
preRes = map.get(preDigitCount - 1).get(num.substring(0, mid));
}
long postRes = 1;
String str = num.substring(mid + 1) + "*";
int left = 0;
int right = left;
while (right < str.length()) {
while (right < str.length() && Character.isDigit(str.charAt(right))) {
right++;
}
if (left < right) {
postRes *= Long.valueOf(str.substring(left, right));
}
left = right + 1;
right = left;
}
if (mid >= 0) {
if (num.charAt(mid) == '+') {
return preRes + postRes;
} else {
return preRes - postRes;
}
} else {
return postRes;
}
}
private long Blank(String num) {
int mid = num.length() - 1;
while (mid >= 0) {
if (!Character.isDigit(num.charAt(mid))) {
break;
}
mid--;
}
int preDigitCount = 0;
for (int i = 0; i < mid; i++) {
if (Character.isDigit(num.charAt(i))) {
preDigitCount++;
}
}
long preRes = 0;
if (preDigitCount > 0) {
preRes = map.get(preDigitCount - 1).get(num.substring(0, mid));
}
long postRes = Long.valueOf(num.substring(mid + 1));
if (num.charAt(mid + 1) == '0') {
return preRes;
}
if (mid >= 0) {
if (num.charAt(mid) == '+') {
return preRes + postRes;
} else if (num.charAt(mid) == '-') {
return preRes - postRes;
} else {
return multiple(num);
}
} else {
return postRes;
}
}
}
class Solution1 {
private int n;
private String num;
private int target;
private List<String> ans;
public List<String> addOperators(String num, int target) {
this.n = num.length();
this.num = num;
this.target = target;
this.ans = new ArrayList<String>();
StringBuffer expr = new StringBuffer();
backtrack(expr, 0, 0, 0);
return ans;
}
private void backtrack(StringBuffer expr, int i, long res, long mul) {
if (i == n) {
if (res == target) {
ans.add(expr.toString());
}
return;
}
int signIndex = expr.length();
if (i > 0) {
expr.append(0);
}
long val = 0;
for (int j = i; j < n && (j == i || num.charAt(i) != '0'); ++j) {
val = val * 10 + num.charAt(j) - '0';
expr.append(num.charAt(j));
if (i == 0) {
backtrack(expr, j + 1, val, val);
} else {
expr.setCharAt(signIndex, '+');
backtrack(expr, j + 1, res + val, val);
expr.setCharAt(signIndex, '-');
backtrack(expr, j + 1, res - val, -val);
expr.setCharAt(signIndex, '*');
backtrack(expr, j + 1, res - mul + mul * val, mul * val);
}
}
expr.setLength(signIndex);
}
}