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

((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就是我们需要得到的所有计算结果。

  1. 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备忘录的方法,来以空间来换取效率。改进程序如下:

  1. 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;
        }
    };
posted @ 2015-11-30 18:36  ZHOU YANG  阅读(182)  评论(0编辑  收藏  举报