• 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;  
        }
    };
  • 相关阅读:
    Android 使用ViewPager结合PhotoView开源组件实现网络图片在线浏览功能
    Android教程 -06 Activity的生命周期
    Android教程 -05 Android6.0权限的管理
    Android 设置ImageView宽度固定,其高度按比例缩放适应
    一技压身,天下行走
    解析P2P金融的业务安全
    Android Listview中Button按钮点击事件冲突解决办法
    Android 动态设置TextView的drawableLeft等属性
    Android教程 -04 启动其它Activity,静态工厂设计模式传递数据
    瞬息之间与时间之门
  • 原文地址:https://www.cnblogs.com/betaa/p/12449104.html
Copyright © 2020-2023  润新知