利用枚举算法解决LeetCode题库第282题给表达式添加运算符问题

282. 给表达式添加运算符

难度:困难

问题描述:

给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,

在 num 的数字之间添加 二元 运算符(不是一元)+、- 或 * ,返回

所有 能够得到 target 的表达式。

注意,返回表达式中的操作数 不应该 包含前导零。

示例 1:

输入: num = "123", target = 6

输出: ["1+2+3", "1*2*3"]

解释: “1*2*3” 和 “1+2+3” 的值都是6。

示例 2:

输入: num = "232", target = 8

输出: ["2*3+2", "2+3*2"]

解释: “2*3+2” 和 “2+3*2” 的值都是8。

示例 3:

输入: num = "3456237490", target = 9191

输出: []

解释: 表达式 “3456237490” 无法得到 9191 。

'''

分析:

枚举算法是一种利用循环结构不断地进行列举和检验,从而完成问题求解的算法。

本问题解决的关键是找到num各个数字之间要插入的运算符共有多少种排列组合,然后利用枚举法列举出num各个数字和运算符组成的表达式,检验该表达式运算结果是否等于target,如果等于,则是一种符合条件的表达式,否则继续列举,直到所有的组合列举完成。

处理问题一共设计两个函数:

  1. pl取排列的意思,pl(n)函数用于生成每个位置有三种运算符“+-*”可选,n个位置共组成多少个运算符的排列组合
  2. cl取处理的意思,cl(num,target)函数先根据num中有多少个数字,得到应该插入多少个运算符,插入运算符的个数等于num中数字个数减1,进而生成运算符的排列组合列表,然后用num中的数字和运算符列表依次生成表达式,检验其运算结果是否等于target,最后将满足条件的表达式添加进列表,并作为结果返回。

程序如下:

#pl(n)函数用于处理每个位置有'+-*'三种运算符可以选择,
#n个位置共有多少种排列组合的问题,并返回运算符排列列表
def pl(n):
    if n==1:
        return ['+','-','*']    
    else:
        b=[]
        for i in '+-*':
            for j in pl(n-1):
                b.append(i+j)
        return b

#根据num和target的值,列举各种可能的运算符组合,检验能够得到target的表达式
def cl(num,target):
    n=len(num)-1 #两个字符中间只能插入一个运算符,n个字符之间只能插入n-1个运算符
    a=pl(n)
    c=[]
    for i in a:
        s=num[0]
        b=list(zip(list(i),list(num[1:])))
        for j in b:
            s=s+j[0]+j[1]
        if eval(s)==target:
            c.append(s)
    return c
#输入
num=input('pls input num=')
target=int(input('pls input target='))

#调用函数并输出结果
myanswer=cl(num,target)
print(myanswer)

运行实例1:

pls input num=234578

pls input target=27

['2*3+4*5-7+8']

运行实例2:

pls input num=232

pls input target=8

['2+3*2', '2*3+2']

运行实例3:

pls input num=23456

pls input target=25

['2+3*4+5+6', '2-3+4*5+6', '2-3-4+5*6', '2*3*4-5+6']

运行实例4:

pls input num=3456

pls input target=15

[]

感悟:

枚举算法虽然从原理上来说是一种笨办法,但它恰恰利用了计算机不怕繁杂,不怕机械枯燥重复,更不会有怨言的特点,是一种解决问题非常实用的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值