LeetCode 241 - Different Ways to Add Parentheses

LeetCode 241 - Different Ways to Add Parentheses

LeetCode 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]

我的解答

这道题也是在分治算法分类中找的,属于Medium难度。

划分括号这个问题很经典,我曾经在离散数学课中接触过。只是那时候问题是求(x~0~ x~1~ x~2~ … x~n~)有多少种划分括号的方式,思路是考虑最后一次运算符的位置。这个位置可以是第一个运算符和最后一个运算符中任何一个,因此我们要遍历一下所有运算符。对于每个运算符,我们再递归地求解这个运算符左边和右边式子的可能数量,二者相乘,即当前运算符位置所具有的总可能数。将所有运算符可能数相加,就可以得到原式具有的所有括号划分的可能。

这个问题其实算是卡特兰数的一个特例。

对于这里的问题,我们只需要对上述问题解答略作修改:将求解子式的可能数改成求解子式可能的结果的集合。

关于时间复杂度,如果假设有n个数字的输入,A(n)为结果的集合大小,T(n)为对应的操作数量,有:

A(n)=n1i=1A(i)A(ni)

T(n)=n1i=1(T(i)+T(ni)+A(i)A(ni))

我不知道怎么证明这里的时间复杂度,如果有心人看到可以讨论一下。不过根据卡特兰数的通项公式 (2nn)/(n+1) ,T(n)至少不是多项式级的。

class Solution {
public:

    vector<int> diffWaysToCompute_helper(string input)
    {
        vector<int>re;//返回结果
        vector<int>operand;//数
        vector<char>binop;//运算符
        vector<int>binop_pos;//运算符所在原字符串的位置
        int tmp=0;
        for(int i=0;i<input.size();i++)
        {
            if(isdigit(input[i]))
            {
                tmp=tmp*10+(input[i]-'0');
            }
            else
            {
                operand.push_back(tmp);
                tmp=0;
                binop.push_back(input[i]);
                binop_pos.push_back(i);
            }
        }
        operand.push_back(tmp);
        if(binop.size()==0)
        {
            return {operand[0]};
        }

        if(binop.size()==1)
        {
            if(binop[0]=='+')
            {
                return {operand[0]+operand[1]};
            }
            else if(binop[0]=='-')
            {
                return {operand[0]-operand[1]};
            }
            else
            {
                return {operand[0]*operand[1]};
            }
        }

        for(int i=0;i<binop.size();i++)
        {
            auto left=diffWaysToCompute_helper(input.substr(0,binop_pos[i]));
            auto right=diffWaysToCompute_helper(input.substr(binop_pos[i]+1,input.size()-binop_pos[i]-1));
            for(auto l:left)
            {
                for(auto r:right)
                {
                    if(binop[i]=='+')
                    {
                        re.push_back(l+r);
                    }
                    else if(binop[i]=='-')
                    {
                        re.push_back(l-r);
                    }
                    else
                    {
                        re.push_back(l*r);
                    }
                }
            }
        }

        return re;
    }

    vector<int> diffWaysToCompute(string input)
    {
        auto r=diffWaysToCompute_helper(input);
        sort(r.begin(),r.end());
        return r;
    }


};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值