【题解】Leetcode.241.Different Ways to Add Parentheses

本文介绍了一种通过分治法解决给定包含数字和运算符的字符串,求出所有可能运算结果的方法。通过递归地分解字符串为左操作数、运算符、右操作数,最终返回所有可能的计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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]

大意:
给定一个数字和操作符的字符串,返回所有运算顺序的结果。

思路:
分治。
分:递归地将一个字符串分成 左操作数,操作符,右操作数,直到这个字符串只剩一个操作数。
治:返回对左操作数序列与右操作数序列的笛卡儿积应用对应操作符产生的序列。

实现:

/*糟糕的实现QAQ*/
#define M 10003
#define OP(op,a,b) (op=='+'?a+b:op=='-'?a-b:a*b) 
class Solution {
public:
vector<int> nums, ops;
void calc(int op, int a, int b, int right, vector<int>&rst){
    vector<int> l,r;
    if(op - a < 2) l.push_back(op-a?OP(ops[op-1],nums[a],nums[a+1]):nums[a]);
    else{
        vector<int> tp;
        for(int i = a;i<op;i++){
            tp.clear();
            calc(i,a,i+1,op,tp);
            for(int i = 0;i<tp.size();i++)
                l.push_back(tp[i]);
        }
    }
    if(right - b < 2) r.push_back(right - b?OP(ops[op+1],nums[b],nums[b+1]):nums[b]);
    else{
        vector<int> tp;
        for(int i = b;i<right;i++){
            tp.clear();
            calc(i,b,i+1,right,tp);
            for(int i = 0;i<tp.size();i++)
                r.push_back(tp[i]);
        }
    }
    for(int i = 0;i<l.size();i++)
        for(int j = 0;j<r.size();j++)
            rst.push_back(OP(ops[op],l[i],r[j]));
}
vector<int> diffWaysToCompute(string input) {
    vector<int> rst;
    int a;
    for(int i = a = 0;input[i];i++){
        if(input[i] == '+' || input[i] == '-' || input[i] == '*'){
            ops.push_back(input[i]);
            nums.push_back(a);
            a = 0;
        }
        else a=a*10+input[i]-'0';
    }
    nums.push_back(a);
    for(int i = 0;i<ops.size();i++)
        calc(i,0,i+1,nums.size()-1,rst);
    if(!rst.size()) rst.push_back(nums[0]);
    return rst;
}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值