您的位置:首页 > Web前端

LeetCode[241. Different Ways to Add Parentheses] 难度[medium]

2016-09-21 23:28 453 查看

题目

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 *.

意思就是给定一条表达式,可以在任意地方加括号改变运算顺序,求可能出现的结果。

算法分析:

这道题主要用到分治的思想,最直接的想法就是对于每个运算符,都把等式分成左右两半,再把两边可能出现的所有结果使用这个运算符运算出结果,如此递归下去,当递归到剩下一个数字就直接返回这个数字,这是未优化的版本。

代码如下(未优化)

class Solution {
public:
vector<int> diffWaysToCompute(string str) {
vector<int> result,r1,r2;
string s1,s2;
bool isNum = true;
int n = str.size();
for(int i=0; i<n; ++i){
if(str[i]=='+'||str[i]=='-'||str[i]=='*'){
isNum = false;
s1 = str.substr(0,i);
s2 = str.substr(i+1,n-i-1);
r1 = diffWaysToCompute(s1);
r2 = diffWaysToCompute(s2);
int n1 =r1.size(), n2 = r2.size();
for(int j=0;j<n1; ++j){
for(int h=0;h<n2;++h){
if(str[i]=='+') result.push_back(r1[j]+r2[h]);
if(str[i]=='-') result.push_back(r1[j]-r2[h]);
if(str[i]=='*') result.push_back(r1[j]*r2[h]);
}
}
}
}
if(isNum){
result.push_back(getNum(str));
}
return result;
}
private:
int getNum(string s){
int n = s.size();
int result;
for(int i=0; i<n;++i){
result *= 10;
result += s[i]-'0';
}
return result;
}
};


这样做在LeetCode上是可以AC的,但效率却不高,因为在递归过程中有许多算重复的式子,比如1+2*3+4, 在(1+2*3)里面要算1+2,在(1+2)里面又要重复算一遍。

优化:这样做之所以慢主要是由于要重复计算同样的等式造成的,所以我们可以用一个map把等式和结果一一对应起来,用空间换取时间,从而提高效率。另外,由于本题输入的是一个字符串,每次运算都要把字符串编程数字,一个数字要重复转换多次,可以提前先把整条式子都转换成数字,从而达到优化效果。

代码实现如下:

class Solution {
public:
vector<int> diffWaysToCompute(string str) {
vector<int> digit,result;
int num = 0;
int n = str.size();
for(int i=0; i<n; ++i){
if(isdigit(str[i])){
num *= 10;
num += str[i]-'0';
}
else{
digit.push_back(num);
num = 0;
digit.push_back(str[i]);
}
}
digit.push_back(num);
int size = digit.size();
result = getResult(digit,0,size-1);

return result;
}

private:
map<int,vector<int> > record;
vector<int> getResult(vector<int> &digit,int low,int high) {
int n = digit.size();
int key = low*(n+1)+high;
if(record.find(key)!=record.end())
return record[key];
vector<int> result,r1,r2;
if(low+1==high || low==high){
result.push_back(digit[low]);
}
for(int i=low+1; i<high; i+=2){
r1 = getResult(digit,low,i);
r2 = getResult(digit,i+1,high);
int n1 =r1.size(), n2 = r2.size();
for(int j=0;j<n1; ++j){
for(int h=0;h<n2;++h){
if(digit[i]=='+')   result.push_back(r1[j]+r2[h]);
if(digit[i]=='-')   result.push_back(r1[j]-r2[h]);
if(digit[i]=='*')   result.push_back(r1[j]*r2[h]);
}
}
}
record[key] = result;
return result;
}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 分治算法