241. Different Ways to Add Parentheses
题目
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: "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
解题思路
可以利用分治算法:在遍历字符串时,遇到运算符,则将字符串分为2部分,分别进行计算,将计算得到的2组值交叉进行运算即可。在计算2个子串时,又可以将子串分为更小的子串,最后将得到一个没有运算符而只有数字的字符串。
代码如下:
class Solution {
public:
vector<int> diffWaysToCompute(string input) {
vector<int> result;
for (int i=0; i<input.size(); i++){
if (input[i] < '0'){
vector<int> v1 = diffWaysToCompute(input.substr(0,i));
vector<int> v2 = diffWaysToCompute(input.substr(i+1));
switch(input[i]){
case '+':
for (int num1: v1){
for (int num2: v2){
result.push_back(num1+num2);
}
}
break;
case '-':
for (int num1: v1){
for (int num2: v2){
result.push_back(num1-num2);
}
}
break;
default:
for (int num1: v1){
for (int num2: v2){
result.push_back(num1*num2);
}
}
break;
}
}
}
if (result.empty()){
result.push_back(atoi(input.c_str()));
}
return result;
}
};
改进方案
上述方案遍历时,每次遇到运算符,都将进行递归,直到子串只有数字。而在每次递归中,之前已经递归计算过的子串的值都需要重新计算。可以利用哈希map将某个字符串计算出的值存储起来,下次遇到该字符串时,可以直接得到它的值而无须再次递归计算。
代码如下:
class Solution {
public:
unordered_map<string, vector<int>> m;
vector<int> diffWaysToCompute(string input) {
if (m.count(input) != 0) return m[input];
vector<int> result;
for (int i=0; i<input.size(); i++){
if (input[i] == '+' || input[i] == '-' || input[i] == '*'){
vector<int> v1 = diffWaysToCompute(input.substr(0,i));
vector<int> v2 = diffWaysToCompute(input.substr(i+1));
for (int num1: v1){
for (int num2: v2){
if (input[i] == '+')
result.push_back(num1+num2);
else if (input[i] == '-')
result.push_back(num1-num2);
else result.push_back(num1*num2);
}
}
}
}
if (result.empty()){
result.push_back(atoi(input.c_str()));
}
m[input] = vector<int>(result.begin(), result.end());
return result;
}
};