282 Expression Add Operators 给表达式添加运算符

Posted lina2014

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了282 Expression Add Operators 给表达式添加运算符相关的知识,希望对你有一定的参考价值。

给定一个仅包含0-9的字符串和一个目标值,返回在数字之间添加了二元运算符(不是一元的) +、-或*之后所有能得到目标值的情况。
例如:
"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 -> []
详见:https://leetcode.com/problems/expression-add-operators/description/

Java实现:

思路:
因为要输出所有可能的情况,必定是用深度优先搜索。问题在于如何将问题拆分成多次搜索。加减法很好处理,每当截出一段数字时,将之前计算的结果加上或者减去这个数,就可以将剩余的数字字符串和新的计算结果代入下一次搜索中了,直到计算结果和目标一样,就完成了一次搜索。然而,乘法如何处理呢?这里需要用一个变量记录乘法当前累乘的值,直到累乘完了,遇到下一个加号或减号再将其算入计算结果中。这里有两种情况:

乘号之前是加号或减号,例如2+3*4,在2那里算出来的结果,到3的时候会加上3,计算结果变为5。在到4的时候,因为4之前选择的是乘号,这里3就应该和4相乘,而不是和2相加,所以在计算结果时,要将5先减去刚才加的3得到2,然后再加上3乘以4,得到2+12=14,这样14就是到4为止时的计算结果。
另外一种情况是乘号之前也是乘号,如果2+3*4*5,这里到4为止计算的结果是14了,然后到5的时候又是乘号,这时候要把刚才加的3*4给去掉,然后再加上3*4*5,也就是14-3*4+3*4*5=62。这样5的计算结果就是62。
因为要解决上述几种情况,需要几个变量,一个是记录上次的计算结果preRes,一个是记录上次被加或者被减的数preNum,一个是当前准备处理的数curNum。当下一轮搜索是加减法时,preNum就是简单换成curNum,当下一轮搜索是乘法时,preNum是preNum乘以curNum。

注意:
第一次搜索不添加运算符,只添加数字,就不会出现+1+2这种表达式了。
截出的数字不能包含0001这种前面有0的数字,但是一个0是可以的。这里一旦截出的数字前导为0,就可以return了,因为说明前面就截的不对,从这之后都是开始为0的,后面也不可能了。

class Solution {
    public List<String> addOperators(String num, int target) {
        List<String> res= new ArrayList<String>();
        helper(num, target, "", 0, 0,res);
        return res;
    }
    private void helper(String num, int target, String tmp, long preRes, long preNum,List<String> res){
        // 如果计算结果等于目标值,且所有数都用完了,则是有效结果
        if(preRes == target && num.length() == 0){
            String exp = new String(tmp);
            res.add(exp);
            return;
        }
        // 搜索所有可能的拆分情况
        for(int i = 1; i <= num.length(); i++){
            String curStr = num.substring(0, i);
            // 对于前导为0的数予以排除
            if(curStr.length() > 1 && curStr.charAt(0) == \'0\'){
                // 这里是return不是continue
                return;
            }
            // 得到当前截出的数
            long curNum = Long.parseLong(curStr);
            // 去掉当前的数,得到下一轮搜索用的字符串
            String next = num.substring(i);
            // 如果不是第一个字母时,可以加运算符,否则只加数字
            if(tmp.length() != 0){
                // 乘法
                helper(next, target, tmp+"*"+curNum, (preRes - preNum) + preNum * curNum, preNum * curNum,res);
                // 加法
                helper(next, target, tmp+"+"+curNum, preRes + curNum, curNum,res);
                // 减法
                helper(next, target, tmp+"-"+curNum, preRes - curNum, -curNum,res); 
            } else {
                // 第一个数
                helper(next, target, curStr, curNum, curNum,res);
            }

        }
    }
}

参考:https://segmentfault.com/a/1190000003797204

C++实现:

class Solution {
public:
    vector<string> addOperators(string num, int target) {
        vector<string> res;
        addOperatorsDFS(num, target, 0, 0, "", res);
        return res;
    }
    void addOperatorsDFS(string num, int target, long long diff, long long curNum, string out, vector<string> &res) {
        if (num.size() == 0 && curNum == target) 
        {
            res.push_back(out);
        }
        for (int i = 1; i <= num.size(); ++i) 
        {
            string cur = num.substr(0, i);
            if (cur.size() > 1 && cur[0] == \'0\')
            {
                return;
            }
            string next = num.substr(i);
            if (out.size() > 0)
            {
                addOperatorsDFS(next, target, stoll(cur), curNum + stoll(cur), out + "+" + cur, res);
                addOperatorsDFS(next, target, -stoll(cur), curNum - stoll(cur), out + "-" + cur, res);
                addOperatorsDFS(next, target, diff * stoll(cur), (curNum - diff) + diff * stoll(cur), out + "*" + cur, res);
            }
            else 
            {
                addOperatorsDFS(next, target, stoll(cur), stoll(cur), cur, res);
            }
        }
    }
};

 参考:https://www.cnblogs.com/grandyang/p/4814506.html

以上是关于282 Expression Add Operators 给表达式添加运算符的主要内容,如果未能解决你的问题,请参考以下文章

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java