力扣每日一题2021-10-16给表达式添加运算符


282.给表达式添加运算符

题目描述

给表达式添加运算符


思路:回溯

回溯

假定字符串num长度为n,为构建表达式,可以往num中间的n-1个空隙添加+号、-号、*号或者不添加符号。
使用回溯法模拟整个过程,从左往右构建表达式,并实时计算表达式的结果。由于乘法运算符优先级高于加减法运算符,还需要保存最后一个连乘串的运算结果。
定义递归回溯函数backtrack(cur, i, res, mul),其中:

  • cur表示当前构建出的表达式;
  • i表示枚举到num中的第i个数字;
  • res表示当前表达式计算的结果;
  • mul表示表达式最后一个连乘串的结果。
    该函数需要讨论两种情况:
  • i = n,说明表达式构造完成,如果此时res与target相等,则找到了一个可行解,将cur作为答案返回放入答案列表中,结束当前递归;
  • i < n,枚举当前表达式末尾要添加的符号(+、-、*)以及该符号之后需要截取多少位数字。设该符号之后的数字为val,按符号分类讨论:
    • 若添加+号,则res增加val,且val单独组成表达式最后一个连乘串;
    • 若添加-号,则res减少val,且-val单独组成表达式最后一个连乘串;
    • 若添加号,由于乘法运算优先级高于加法和减法运算,我们需要对res撤销之前mul的计算结果,并添加新的连乘结果mulval,也就是将res减少mul并增加mul*val。
      回溯
class Solution:
    def addOperators(self, num: str, target: int) -> List[str]:
        n = len(num)
        ans = []

        def backtrack(cur, i, res, mul):
            if i == n:
                if res == target:
                    ans.append("".join(cur))
                return
            signIndex = len(cur)
            if i > 0:
                # 占位,下面填充符号
                cur.append("")
            val = 0
            # 枚举截取的数字长度
            for j in range(i, n):
                # 数字可以是单个0,但不能是前导0
                if j > i and num[i] == '0':
                    break
                val = val * 10 + int(num[j]) 
                cur.append(num[j])
                # 表达式开头不加符号
                if i == 0:
                    backtrack(cur, j+1, val, val)
                # 枚举符号
                else:
                    cur[signIndex] = '+'; backtrack(cur, j+1, res+val, val)
                    cur[signIndex] = '-'; backtrack(cur, j+1, res-val, -val)
                    cur[signIndex] = '*'; backtrack(cur, j+1, res-mul+mul*val, mul*val)
            del cur[signIndex:]


        backtrack([], 0, 0, 0)
        return ans
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值