LC282. Expression Add Operators

给一串数字,在数字之间添加二元运算符 + - * ,使表达式的运算结果为 target ,输出所有可能的添加方式。

DFS:设共有 n 个数字,共有 n-1 个中间位置需要插入符号,插入的符号为:

''(0) '+'(1) '-'(2) '*'(3)

插入''(0)表示不插入数字,即相邻的数字组成更大的数字,每个位置有4中插法,共有$4^{n-1}$种插法,NP问题,只能用dfs暴力搜索。

每得到一个插满符号的表达式,需要计算表达式的值,与 target 比较。

计算表达式的值:用一个符号栈(单调栈,栈底符号优先级低)和一个值栈来计算,符号栈中最多只能有2个符号+/- 和*,同优先级都存在时需要计算出相应结果再入栈。

此题可以在插入符号的同时计算表达式的值,速度更快,方法如下:

class Solution {
public:
    typedef long long LL;
    vector<string> ans;
    vector<int> nu;
    vector<int> nop;
    int n, tar;
    // 0 '' 1 '+' 2 '-' 3 '*'
    void dfs(int cur, int op1, int op2, LL n1, LL n2, LL n3, int zero) {
        if (cur == n - 1) {
            if (op2) n2 *= n3;
            if (op1 == 1) n1 += n2;
            else n1 -= n2;
            if (n1 == tar) {
                string s;
                for (int i = 0; i < n - 1; ++i) {
                    s += to_string(nu[i]);
                    if (nop[i] == 1)
                        s += '+';
                    else if (nop[i] == 2) 
                        s += '-';
                    else if (nop[i] == 3)
                        s += '*';
                }
                s += to_string(nu[n - 1]);
                ans.push_back(s);
            }
            return;
        }
        cur++;
        int v = nu[cur];
        
        // 0 ''
        if (!zero) {
            nop[cur - 1] = 0;
            if (op2) dfs(cur, op1, op2, n1, n2, n3 * 10 + v, 0);
            else dfs(cur, op1, op2, n1, n2 * 10 + v, 0, 0);
        }
        
        // 3 '*'
        nop[cur - 1] = 3;
        if (op2) n2 *= n3, n3 = 0;
        dfs(cur, op1, 3, n1, n2, v, v == 0);
        
        // 1 '+'
        nop[cur - 1] = 1;
        if (op1 == 1) n1 += n2, n2 = 0;
        else n1 -= n2, n2 = 0;
        dfs(cur, 1, 0, n1, v, 0, v == 0);
        
        // 2 '-'
        nop[cur - 1] = 2;
        dfs(cur, 2, 0, n1, v, 0, v == 0);
    }
    vector<string> addOperators(string num, int target) {
        for (char c : num)
            nu.push_back(c - '0');
        n = nu.size();
        if (n == 0) return ans;
        tar = target;
        nop.assign(n, 0);
        dfs(0, 1, 0, 0, nu[0], 0, nu[0] == 0);
        return ans;  
    }
};

 

posted @ 2020-03-09 15:46  betaa  阅读(110)  评论(0编辑  收藏  举报