题目描述
Given a string expression
of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. You may return the answer in any order.
Example 1:
Input: expression = "2-1-1" Output: [0,2] Explanation: ((2-1)-1) = 0 (2-(1-1)) = 2
Example 2:
Input: expression = "2*3-4*5" Output: [-34,-14,-10,-10,10] Explanation: (2*(3-(4*5))) = -34 ((2*3)-(4*5)) = -14 ((2*(3-4))*5) = -10 (2*((3-4)*5)) = -10 (((2*3)-4)*5) = 10
Constraints:
1 <= expression.length <= 20
expression
consists of digits and the operator'+'
,'-'
, and'*'
.- All the integer values in the input expression are in the range
[0, 99]
.
解题思路
【C++】
1. 分治递归
class Solution {
unordered_map<string, vector<int>> m;
public:
vector<int> diffWaysToCompute(string expression) {
if (m.count(expression)) return m[expression];
vector<int> ways;
for (int i = 0; i < expression.length(); ++i) {
char c = expression[i];
if (c == '+' || c == '-' || c == '*') {
vector<int> left = diffWaysToCompute(expression.substr(0, i));
vector<int> right = diffWaysToCompute(expression.substr(i + 1));
for (const int & l : left) {
for (const int & r : right) {
switch (c) {
case '+': ways.push_back(l + r); break;
case '-': ways.push_back(l - r); break;
case '*': ways.push_back(l * r); break;
}
}
}
}
}
if (ways.empty()) {ways.push_back(stoi(expression));}
m[expression] = ways;
return ways;
}
};
2. 动态规划
class Solution {
public:
vector<int> diffWaysToCompute(string expression) {
vector<int> data;
vector<char> ops;
int num = 0;
char op = ' ';
istringstream ss(expression + "+");
while (ss >> num && ss >> op) {
data.push_back(num);
ops.push_back(op);
}
int n = data.size();
vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>()));
for (int i = 0; i < n; ++i) {
dp[i][i].push_back(data[i]);
for (int j = i - 1; j >= 0; --j) {
for (int k = j; k < i; k += 1) {
for (auto left : dp[j][k]) {
for (auto right : dp[k+1][i]) {
int val = 0;
switch (ops[k]) {
case '+': val = left + right; break;
case '-': val = left - right; break;
case '*': val = left * right; break;
}
dp[j][i].push_back(val);
}
}
}
}
}
return dp[0][n-1];
}
};
【Java】
class Solution {
private Map<String, List<Integer>> m = new ConcurrentHashMap<>();
public List<Integer> diffWaysToCompute(String expression) {
if (m.containsKey(expression)) {return m.get(expression);}
List<Integer> ways = new ArrayList<>();
for (int i = 0; i < expression.length(); ++i) {
char c = expression.charAt(i);
if (c == '+' || c == '-' || c == '*') {
List<Integer> left = diffWaysToCompute(expression.substring(0, i));
List<Integer> right = diffWaysToCompute(expression.substring(i + 1));
for (int l : left) {
for (int r : right) {
switch (c) {
case '+': ways.add(l + r); break;
case '-': ways.add(l - r); break;
case '*': ways.add(l * r); break;
}
}
}
}
}
if (ways.isEmpty()) {ways.add(Integer.parseInt(expression));}
m.put(expression, ways);
return ways;
}
}