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"
.
((2-1)-1) = 0 (2-(1-1)) = 2
Output: [0, 2]
Example 2
Input: "2*3-4*5"
(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
Output: [-34, -14, -10, -10, 10]
思路:递归。对字符串input,循环遍历,如果input[i]是运算符,将其切割为两个字符串,两个字符串的下标范围分别是0~i-1,i+1~n-1,递归求出这两个字符串所有组合计算的结果,置于result1和result2之中。然后对result1和result2之中的所有计算结果,一 一组合,求出对应之前切割的运算符对应的计算结果,计算结果写入result。有一种情况,如果刚开始传入的字符串就是一个数字,那么上述循环过程之中,result的大小并没有发生变化,此时,直接将这个字符串转换为数字,写入result即可。最后返回的result就是我们需要得到的所有计算结果。
-
class Solution { public: vector<int> diffWaysToCompute(string input) { vector<int> result; for(int i=0;i<input.size();i++){ char ch =input[i]; if(ch=='+'||ch=='-'||ch=='*'){ //递归对字符串0~i-1求计算的结果 vector<int> result1=diffWaysToCompute(input.substr(0,i)); //递归对字符串i+1~n-1求计算的结果 vector<int> result2=diffWaysToCompute(input.substr(i+1)); //对所有的结果,分别配对求与ch对应的计算结果,写入result之中 for(auto x:result1){ for(auto y:result2){ if(ch=='+') result.push_back(x+y); else if(ch=='-') result.push_back(x-y); else result.push_back(x*y); } } } } //如果result.size()==0,标明子串中只有数字,将其转换为数字,写入result之中 if(result.size()==0){ result.push_back(atoi(input.c_str())); } //返回result return result; } };
改进:在这种求法中,有很多重复的子串被重复计算,因此,我们可以利用DP备忘录的方法,来以空间来换取效率。改进程序如下:
-
class Solution { private: unordered_map<string,vector<int>> map; public: vector<int> diffWaysToCompute(string input) { vector<int> result; for(int i=0;i<input.size();i++){ char ch =input[i]; if(ch=='+'||ch=='-'||ch=='*'){ //递归对字符串0~i-1求计算的结果 vector<int> result1= map.find(input.substr(0,i))==map.end()? diffWaysToCompute(input.substr(0,i)):map[input.substr(0,i)]; //递归对字符串i+1~n-1求计算的结果 vector<int> result2= map.find(input.substr(i+1))==map.end()? diffWaysToCompute(input.substr(i+1)) :map[input.substr(i+1)]; //对所有的结果,分别配对求与ch对应的计算结果,写入result之中 for(auto x:result1){ for(auto y:result2){ if(ch=='+') result.push_back(x+y); else if(ch=='-') result.push_back(x-y); else result.push_back(x*y); } } } } //如果result.size()==0,标明子串中只有数字,将其转换为数字,写入result之中 if(result.size()==0){ result.push_back(atoi(input.c_str())); } map[input]=result; //返回result return result; } };