leetcode学习篇三——Different Ways to Add Parentheses

本文通过一个LeetCode上的中等难度题目,探讨如何利用分治法来解决包含多种运算符的数学表达式的计算问题,并逐步改进代码实现,最终通过所有测试案例。

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

看到leetcode的题有时还是会懵逼,继续做一下分治的题目,题目如下:
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 *.
难度:medium 通过率:39.2%

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]

因为leetcode上把这道题分在分治算法模块,所以看到这道题思路就往分治法思考,把长字符串分解成小字符串,小字符串再分,然而在哪里分呢,于是尝试遇到运算符就分,写出了以下代码:

class Solution {
public:
    vector<int> diffWaysToCompute(string input) {
        vector<int> result;   //储存结果
        for(int i = 0; i < input.length(); i++) {
            if(input[i] == '+' || input[i]== '-' || input[i]=='*') {
                //向量l和r分别存储运算符左右式子计算的结果 
                vector<int> l = diffWaysToCompute(input.substr(0, i));
                vector<int> r = diffWaysToCompute(input.substr(i+1, input.size()-i-1));
                if(input[i]=='+') result.push_back(l[0]+r[0]);
                else if(input[i]=='*') result.push_back(l[0]*r[0]);
                else if(input[i]=='-') result.push_back(l[0]-r[0]); 
            }
        } 
        if(result.empty()) {
            result.push_back(input[0]-'0');   //没有运算符,数字进向量 
        }
        return result;   
    }
};

运行了一下案例2,错了,少了两种结果,于是开始断点debug,发现在计算右边的式子的时候如果大于三个的话,计算结果不知一个,所以向量r的大小不只为1,而代码中直接使用了下标0,所以导致输出结果情况减少。
于是加上循环,对向量r和l大小的双重循环,得到以下代码:

class Solution {
public:
    vector<int> diffWaysToCompute(string input) {
        vector<int> result;   //储存结果
        for(int i = 0; i < input.length(); i++) {
            if(input[i] == '+' || input[i]== '-' || input[i]=='*') {
                //向量l和r分别存储运算符左右式子计算的结果 
                vector<int> l = diffWaysToCompute(input.substr(0, i));
                vector<int> r = diffWaysToCompute(input.substr(i+1, input.size()-i-1));
                for(int j = 0; j < l.size(); j++) {
                    for(int k = 0; k < r.size(); k++) {
                        if(input[i]=='+') {
                            result.push_back(l[j]+r[k]);
                        } 
                        else if(input[i]=='*') result.push_back(l[j]*r[k]);
                        else if(input[i]=='-') result.push_back(l[j]-r[k]);
                    }
                }  
            }
        } 
        if(result.empty()) {
            result.push_back(input[0]-'0');   //没有运算符,数字进向量 
        }
        return result;       
    }
};

哈哈,运行了两个案例,全部正确,提交了,WA……,看了一下解析,出错样例是输入11我的代码输出1,这次很快找到问题所在,因为只有一个数,所以肯定在以下这段代码出问题:

if(result.empty()) {
    result.push_back(input[0]-'0');   //没有运算符,数字进向量 
}

恩,果然……这样写的话只考虑到一位数的情况,于是修改代码,调用函数解决了这个问题,再次提交,AC

vector<int> diffWaysToCompute(string input) {
    vector<int> result;   //储存结果
    for(int i = 0; i < input.length(); i++) {
        if(input[i] == '+' || input[i]== '-' || input[i]=='*') {
            //向量l和r分别存储运算符左右式子计算的结果 
            vector<int> l = diffWaysToCompute(input.substr(0, i));
            vector<int> r = diffWaysToCompute(input.substr(i+1, input.size()-i-1));
            for(int j = 0; j < l.size(); j++) {
                for(int k = 0; k < r.size(); k++) {
                    if(input[i]=='+') {
                        result.push_back(l[j]+r[k]);
                    } 
                    else if(input[i]=='*') result.push_back(l[j]*r[k]);
                    else if(input[i]=='-') result.push_back(l[j]-r[k]);
                }
            }  
        }
    } 
    if(result.empty()) {
        result.push_back(atoi(input.c_str()));   //没有运算符,数字进向量 
    }
    return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值