282 给表达式添加运算符

题目描述:
给定一个仅包含数字 0-9 的字符串和一个目标值,在数字之间添加二元运算符(不是一元)+、- 或 * ,返回所有能够得到目标值的表达式。

示例 1:
输入: num = “123”, target = 6
输出: [“1+2+3”, “123”]

示例 2:
输入: num = “232”, target = 8
输出: [“23+2", "2+32”]

示例 3:
输入: num = “105”, target = 5
输出: [“1*0+5”,“10-5”]

示例 4:
输入: num = “00”, target = 0
输出: [“0+0”, “0-0”, “0*0”]

示例 5:
输入: num = “3456237490”, target = 9191
输出: []

方法1:
主要思路:
(1)使用回溯;
(2)将字符串逐渐的分割成各种的不同的长度子串,配以三种符号,生成对应的字符串,并在生成的过程中,计算各个情形下的数值,当到达字符串的末尾时,且计算的数值和给定的目标值一致时,将生成的当前的字符串存入到结果中;
(3)对于每种可能的字符串和对应的符号的选择,需要随后复原原来的字符串;
(4)在添加符号时,考虑到乘号的优先级较高,当出现乘号时,需要将乘号的值进行对应的更新,故需要保存上一个值的大小;
(5)在处理子字符串生成的数字时,考虑到数字的有效性,故当数字第一次出现为0后,需要直接返回,后面的以0作为第一位数字的组成都是无效的;

class Solution {
public:
	//回溯
    void backtrace(string&num,const int& target,vector<string>& res,string& path,int index,long long val,long long mult){
        if(index==num.size()){//终止条件
            if(val==target){//生成了符合要求的字符串
                res.push_back(path);
            }
            return;
        }
        int len=path.size();//原来的字符串的长度,便于后面的复原字符串
        for(int i=index;i<num.size();++i){//当前索引为起始位置,生成各种可能长度的子字符串作为对应的可能的数字
            string str_val=num.substr(index,i-index+1);//当前的子字符串
            long long cur_num=stol(str_val);//子字符串对应的数字
            if(index==0){//起始索引为0,说明是第一个数字,故不需要符号,单独处理
                path+=str_val;
                backtrace(num,target,res,path,i+1,cur_num,cur_num);//更新索引,当前已经计算出来的值,及上一个值
                path.resize(len);//复原字符串
            }
            else {
                path+="+"+str_val;//加号的情形
                backtrace(num,target,res,path,i+1,val+cur_num,cur_num);//更新索引,当前计算出来的值,及上一个值
                path.resize(len);//复原

                path+="-"+str_val;//减号的情形
                backtrace(num,target,res,path,i+1,val-cur_num,-cur_num);
                path.resize(len);

                path+="*"+str_val;//乘号的情形,稍微复杂,因为考虑到优先级,需要重新计算值
                //更新计算的值的方式和上述不同,需要先复原,再处理乘号的结果,并且上一个值的保存也是乘积的结果
                backtrace(num,target,res,path,i+1,val-mult+mult*cur_num,mult*cur_num);
                path.resize(len);//复原
            }
            if(cur_num==0){//避免出现以0作为第一位的多位的数字,此种情形是无效的,如012这种
                return;
            }
        }
    }
    vector<string> addOperators(string num, int target) {
        vector<string> res;//存储结果
        string path="";//存储中间生成的结果
        backtrace(num,target,res,path,0,0,1);
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值