Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.
Example 1:
Input: “2-1-1”
Output: [0, 2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2
Example 2:
Input: “23-45”
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(45))) = -34
((23)-(45)) = -14
((2(3-4))5) = -10
(2((3-4)5)) = -10
(((23)-4)*5) = 10
思路
循环运算符号 + DFS组装两部分结果的运算值。
代码
class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> ret = new LinkedList<Integer>();
for (int i=0; i<input.length(); i++) {
if (input.charAt(i) == '-' ||
input.charAt(i) == '*' ||
input.charAt(i) == '+' ) {
String part1 = input.substring(0, i);
String part2 = input.substring(i+1);
List<Integer> part1Ret = diffWaysToCompute(part1);
List<Integer> part2Ret = diffWaysToCompute(part2);
for (Integer p1 : part1Ret) {
for (Integer p2 : part2Ret) {
int c = 0;
switch (input.charAt(i)) {
case '+': c = p1+p2;
break;
case '-': c = p1-p2;
break;
case '*': c = p1*p2;
break;
}
ret.add(c);
}
}
}
}
if (ret.size() == 0) {
ret.add(Integer.valueOf(input));
}
return ret;
}
}
优化:Memo + DFS
There are many repeating subquestions in this recursive method, therefore, we could use dynamic programming to avoid this situation by saving the results for subquestions. Here is the DP solution.
class Solution {
public List<Integer> diffWaysToCompute(String input) {
Map<String, List<Integer>> cache = new HashMap<>();
return ToCompute(input, cache);
}
public List<Integer> ToCompute(String input, Map<String, List<Integer>> cache) {
List<Integer> ret = new LinkedList<Integer>();
int length = input.length();
for (int i = 0; i < length; i++) {
char c = input.charAt(i);
if (c == '-' || c == '*' || c == '+' ) {
String part1 = input.substring(0, i);
String part2 = input.substring(i+1);
List<Integer> ret1 = new LinkedList<>();
List<Integer> ret2 = new LinkedList<>();
if(cache.get(part1) != null)
ret1 = cache.get(part1);
else
ret1 = ToCompute(part1, cache);
if(cache.get(part2) != null)
ret2 = cache.get(part2);
else
ret2 = ToCompute(part2, cache);
for (Integer p1 : ret1) {
for (Integer p2 : ret2) {
int cc = 0;
switch (input.charAt(i)) {
case '+': cc = p1+p2;
break;
case '-': cc = p1-p2;
break;
case '*': cc = p1*p2;
break;
}
ret.add(cc);
}
}
}
}
if (ret.size() == 0) {
ret.add(Integer.valueOf(input));
}
cache.put(input,ret);
return ret;
}
}