题目:
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 -> []


题目看上去有点像dp,但又无法表示状态。
又发现要求输出所有结果,果断爆搜了。
思想就是每次在当前串后面添加一个运算符,显然加减号可以直接添加,然后可以很方便更新当前计算结果。
但乘法则需要考虑前面的数字是什么,所以需要在搜索过程中添加一个新的域:last_val。
设当前运串后添加了“x”,则计算结果增量为last_val(x-1)。
其中x之所以减1是因为last_val在当前计算结果中已经包含一份了,所以增量就是x-1份last_val。
这里写图片描述

class Solution {
public:
    vector<string> ans;
    vector<string> addOperators(string num, int target) {
        ans.clear();
        for (int i = 0; i < num.length(); i++) {
            string sub_str = num.substr(0, i + 1);
            long long x = toNumber(sub_str);
            calc(num, i + 1, sub_str, x, x, target);
            if (i == 0 && num[i] == '0') break;
        }
        return ans;
    }

    void calc(string num, int start, string cur_str, long long cur_val, long long last_val, long long target) {
        if (start >= num.length()) {
            if (cur_val == target) ans.push_back(cur_str);
            return;
        }
        for (int i = start; i < num.length(); i++) {
            string sub_str = num.substr(start, i - start + 1);
            long long x = toNumber(sub_str);
            calc(num, i + 1, cur_str + "+" + sub_str, cur_val + x, x, target);
            calc(num, i + 1, cur_str + "-" + sub_str, cur_val - x, -x, target);
            calc(num, i + 1, cur_str + "*" + sub_str, cur_val + last_val * (x - 1), last_val * x, target);
            if (i == start && num[i] == '0') break;
        }
    }

    long long toNumber(string s) {
        long long rt = 0;
        for (int i = 0; i < s.length(); i++)
            rt = rt * 10 + s[i] - '0';
        return rt;
    }
};
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐