leetcode(282): Expression Add Operators

本文介绍了一种使用深度优先搜索算法解决的问题:给定一个只包含数字0-9的字符串和一个目标值,返回所有可能在数字间添加二元运算符(+、- 或 *)使表达式计算结果等于目标值的方法。

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

Given a string that contains only digits 0-9 and a target value,return all possibilities to add binary operators (not unary) +, -, or * between the digits so they evaluate to the target value.

Examples:

“123”, 6 -> [“1+2+3”, “1*2*3”]
“232”, 8 -> [“2*3+2”, “2+3*2”]
“105”, 5 -> [“1*0+5”,”10-5”]
“00”, 0 -> [“0+0”, “0-0”, “0*0”]
“3456237490”, 9191 -> []

分析:题意为在给定的字符串中添加运算符,使得表达式的值等于给定的target。

思路是用深度优先搜索算法,先截取一段数字,将之前的计算结果加上或者减去这个数字,在将新的结果和剩余的数字串带入下一轮搜索中,直到最后结果等于目标值target。将大问题分解成多个小问题,再将所有小问题的解合起来,形成大问题的解,就是分治算法。

注意:

在2+3*4这个表达式中,当计算到3时,后面是号,由四则运算法则需要先算号,所以不能从左到右依次计算,而应该先把3*4的值算出来再和2相加得到结果2+12=14才是正确的。因此需要设定一个变量currRes保存计算到当前数字的结果,在这个例子中是2+3=5,当要处理数字4时,由于前面运算符是*,设定一个变量prevNum保存上一次处理的数字,这个例子中prevNum=3,设定一个变量currNum保存当前处理的数,此处currNum=4,所以带入下一轮搜索的currRes=currRes-prevNum+prevNum*currNum,还要记得更新prevNum的值,这个例子中prevNum=3*4.

若截取到的数字形如”001”的时候需要处理前面的0

public class Solution {
    public static List<String> addOperators(String num, int target) {
        List<String> res  = new LinkedList<String>();
        if(num==null || num.length()==0) return res;
        helper(res,num, target, "", 0, 0);
        return res;
    }

    private static void helper(List<String> res,String num, int target, String tmp, long currRes, long prevNum){
        // 如果计算结果等于目标值,且所有数都用完了,则是有效结果
        if(currRes == target && num.length() == 0){
            String exp = new String(tmp);
            res.add(exp);
            return;
        }
        // 搜索所有可能的拆分情况
        for(int i = 1; i <= num.length(); i++){
            String currStr = num.substring(0, i);
            // 对于前导为0的数予以排除
            if(currStr.length() > 1 && currStr.charAt(0) == '0'){
                return;
            }
            // 得到当前截出的数
            long currNum = Long.parseLong(currStr);//防止越界
            // 去掉当前的数,得到下一轮搜索用的字符串
            String next = num.substring(i);
            //不是第一个数字
            if(tmp.length() != 0){
                // 乘法
                helper(res,next, target, tmp+"*"+currNum, (currRes - prevNum) + prevNum * currNum, prevNum * currNum);
                // 加法
                helper(res,next, target, tmp+"+"+currNum, currRes + currNum, currNum);
                // 减法
                helper(res,next, target, tmp+"-"+currNum, currRes - currNum, -currNum); 
            } else {
            //从第一个数字进行处理
                helper(res,next, target, currStr, currNum, currNum);
            }

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值