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.
Adding parentheses is like choosing an operator and calculating the results on both sides.
(a) * (b) <- here a can be the result of long-expression. You can notice the pattern, a long-expression can be recursively scaled down to a number. We just need to dfs on both sides and then calculate the value.
Remember, an expression could have different results, so we need to store these results in an array. When do we need to use the left side and right side's results? we need to use it to find all combinations, so we use two for loops here to match different results on the left and right.
Of course, the time complexity for this algorithm is O(2^n). We would try to use memorization to reduce time.
The map would use the expression as a key and a vector as a value.
The expression is the only status for our dfs or dp.
class Solution {
public:
vector<int> dfs(string e, map<string, vector<int>> &mem){
if(mem.find(e) != mem.end())return mem[e];
vector<int> left, right, res;
for(int i = 0; i < e.length(); i++){
if(e[i] == '*' || e[i] == '-' || e[i] == '+' || e[i] == '/'){
//divide and conquer
left = dfs(e.substr(0, i), mem);
right = dfs(e.substr(i + 1), mem);
}
for(auto l : left){
for(auto r : right){
if(e[i] == '+') res.push_back(l + r);
else if(e[i] == '-')res.push_back(l - r);
else if(e[i] == '*')res.push_back(l * r);
else if(e[i] == '/')res.push_back(l / r);
}
}
}
if(!res.size()) return mem[e] = {stoi(e)};
mem[e] = res;
return res;
}
vector<int> diffWaysToCompute(string expression) {
map<string, vector<int>> m;
return dfs(expression, m);
}
};