• LeetCode-282 Expression Add Operators


    题目描述

    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.

    题目大意

    给定一个只包含0-9的字符串和一个正整数,要求利用二元运算符‘+’,‘-’,‘*’(注意,这些都是二元运算符,并不是一元运算符,也就是说不能有负数)计算出能够等于所给整数的可能的运算式。

    示例

    E1

    Input: num = "123", target = 6
    Output: ["1+2+3", "1*2*3"] 

    E2

    Input: num = "232", target = 8
    Output: ["2*3+2", "2+3*2"]

    E3

    Input: num = "105", target = 5
    Output: ["1*0+5","10-5"]

    E4

    Input: num = "00", target = 0
    Output: ["0+0", "0-0", "0*0"]

    E5

    Input: num = "3456237490", target = 9191
    Output: []

    解题思路

    依次进行递归运算,递归的时候分别进行不同的三种运算,当递归遍历到字符串末尾时,判断生成的结果是否为target,若是则产生一个结果,进行保存。

    由于运算符中有惩罚,因此在进行乘法运算的时候要注意前一个运算符是否为乘法,若不是则要重新计算运算,因为乘法运算优先级高于加法与减法。

    复杂度分析

    时间复杂度:O(N2)

    空间复杂度:O(N)

    代码

    class Solution {
    public:
        vector<string> addOperators(string num, int target) {
            vector<string> res;
            if(num.empty())
                return res;
            // 依次遍历字符串,将第一个数字表示出来
            for(int i = 1; i <= num.length(); ++i) {
                string s = num.substr(0, i);
                // 将第一个数字转为long类型
                long n = stol(s);
                // 若该字符串包含前缀零,则继续
                if(to_string(n).size() != s.size())
                    continue;
                // 进行dfs递归
                dfs(res, num, target, s, i, n, n, '#');
            }
            
            return res;
        }
        // res:最终结果数组
        // num:给定的数字字符串
        // target:目标结果
        // ans:递归当前的计算式
        // pos:当前遍历到字符串的位置
        // pt:之前计算式的总和
        // pn:上一个操作数的值
        // op:上一个操作符
        void dfs(vector<string>& res, const string num, const int target, string ans, int pos, long pt, long pn, char op) {
            // 若满足条件将该算术式加入结果数组
            if(pos == num.size() && pt == target)
                res.push_back(ans);
            // 否则进行递归调用
            else {
                // 遍历剩余数组
                for(int i = pos + 1; i <= num.size(); ++i) {
                    string tmp = num.substr(pos, i - pos);
                    // 将pos-i之间的字符串转为数字
                    long tmpnum = stol(tmp);
                    if(to_string(tmpnum).size() != tmp.size())
                        continue;
                    // 若上一个运算符为‘+’号,则进行正常运算
                    dfs(res, num, target, ans + '+' + tmp, i, pt + tmpnum, tmpnum, '+');
                    // 若上一个运算符为‘-’号,则进行正常运算
                    dfs(res, num, target, ans + '-' + tmp, i, pt - tmpnum, tmpnum, '-');
                    // 若上一个运算符为‘*’号,需要进行判断上一个为运算符的符号,分别进行不同的运算                
                    dfs(res, num, target, ans + '*' + tmp, i, (op == '+') ? pt - pn + pn * tmpnum : ((op == '-') ? pt + pn - pn * tmpnum : pn * tmpnum), tmpnum * pn, op);                
                }
            }
        }
    };
  • 相关阅读:
    高精度不会的迅速暴击此处
    高精度不会的迅速暴击此处
    codevs3243:区间翻转,线段树
    codevs3243:区间翻转,线段树
    codevs3243:区间翻转,线段树
    [NOIP2010]关押罪犯
    [NOIP2010]关押罪犯
    [NOIP2010]关押罪犯
    [UVALive 6693]Flow Game计算几何,线代相交
    2017 省赛选拨 火车入站 CSU 1757 模拟
  • 原文地址:https://www.cnblogs.com/heyn1/p/11138900.html
Copyright © 2020-2023  润新知