241. Different Ways to Add Parentheses

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.

Example 1:

Input: "2-1-1"
Output: [0, 2]
Explanation: 
((2-1)-1) = 0 
(2-(1-1)) = 2

Example 2:

Input: "2*3-4*5"
Output: [-34, -14, -10, -10, 10]
Explanation: 
(2*(3-(4*5))) = -34 
((2*3)-(4*5)) = -14 
((2*(3-4))*5) = -10 
(2*((3-4)*5)) = -10 
(((2*3)-4)*5) = 10

這種DFS recursion常常會有重複的計算,所以用一個 hashmap去紀錄某個substring的結果。在helper function中的for loop試著想找到operator,找到+或-或*之後,就可以把string分成兩個部分,然後分別用helper func得到各自的結果。最後把兩邊結果試著配成一對。如果該層的res array裡面沒有任何數字,代表該substring沒有任何運算子,全部看作一個數字,直接加到res array裡。

// Top-Down Dynamic Programming with Memoization
vector<int> helper(const string& input, unordered_map<string, vector<int> >& memo) {
    if (memo.count(input)) return memo[input];
    vector<int> res;
    for (int i = 0; i < input.size(); ++i) {
        char ch = input[i];
        if (!(ch == '+' || ch == '-' || ch == '*')) continue;
        string str1 = input.substr(0, i), str2 = input.substr(i + 1);
        const vector<int>& res1 = memo.count(str1) ? memo[str1] : helper(str1, memo);
        const vector<int>& res2 = memo.count(str2) ? memo[str2] : helper(str2, memo);
        for (int n1 : res1) {
            for (int n2 : res2) {
                switch (ch) {
                    case '+':
                        res.emplace_back(n1 + n2);
                        break;
                    case '-':
                        res.emplace_back(n1 - n2);
                        break;
                    case '*':
                        res.emplace_back(n1 * n2);
                        break;
                }
            }
        }
    }
    if (res.empty()) res.emplace_back(stoi(input));
    return memo[input] = res;
}
vector<int> diffWaysToCompute(string input) {
    unordered_map<string, vector<int> > memo;
    return helper(input, memo);
}

Last updated

Was this helpful?