java 282. Expression Add Operators.java

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 282. Expression Add Operators.java相关的知识,希望对你有一定的参考价值。

// https://discuss.leetcode.com/topic/88600/c-divide-and-conquer-solution-69-ms
class Solution {
    int toInt(const string& num, int i, int len) {
        if (len < 1 || len > 10) return -1;
        if (len > 1 && num[i] == '0') return -1;
        int n = 0;
        for (int j=i; j < i + len; j++) {
            int val = num[j] - '0';
            if (n > (numeric_limits<int>::max() - val)/10) return -1;
            n = (n * 10) + val;
        }
        return n;
    }
    
    unordered_map<int, vector<string>> multiplyHelper(const string& num, int i, int len) {
        unordered_map<int, vector<string>> result;
        int n = toInt(num, i, len); // single value (no multiply)
        if (n >= 0) {
            result[n].push_back(num.substr(i, len));
        }
        if (len >= 2) {
            for (int j = 1; j <= 10 && j < len; j++) {
                int n = toInt(num, i, j);
                if (n < 0) continue;
                unordered_map<int, vector<string>> right = multiplyHelper(num, i + j, len - j);
                for (auto pair : right) {
                    if (n == 0 || pair.first <= numeric_limits<int>::max()/n) {
                        for (string s : pair.second) {
                            result[n * pair.first].push_back(num.substr(i, j) + "*" + s);
                        }
                    }
                }
            }
        }
        return result;
    }
    
    unordered_map<int, vector<string>> addOperatorsHelper(const string& num, int i, int len, const set<int>& target) {
        unordered_map<int, vector<string>> result = multiplyHelper(num, i, len); // No add/subtract
        if (len >= 2) {
            for (int j = 1; j < len; j++) {
                unordered_map<int, vector<string>> right = multiplyHelper(num, i + j, len - j);
                set<int> targetLeft;
                for (auto pairRight : right) {
                    int right = pairRight.first;
                    for (int targ : target) {
                        if (targ >= numeric_limits<int>::min() + right) {
                            targetLeft.insert(targ - right);
                        }
                        if (targ <= numeric_limits<int>::max() - right) {
                            targetLeft.insert(targ + right);
                        }
                    }
                }
                
                unordered_map<int, vector<string>> left = addOperatorsHelper(num, i, j, targetLeft);
                for (auto pairLeft : left) {
                    for (auto pairRight : right) {
                        if (pairLeft.first <= numeric_limits<int>::max() - pairRight.first) {
                            if (target.find(pairLeft.first + pairRight.first) != target.end()) {
                                for (string sleft : pairLeft.second) {
                                    for (string sright : pairRight.second) {
                                        result[pairLeft.first + pairRight.first].push_back(sleft + "+" + sright);
                                    }
                                }
                            }
                        }
                        if (pairLeft.first >= numeric_limits<int>::min() + pairRight.first) {
                            if (target.find(pairLeft.first - pairRight.first) != target.end()) {
                                for (string sleft : pairLeft.second) {
                                    for (string sright : pairRight.second) {
                                        result[pairLeft.first - pairRight.first].push_back(sleft + "-" + sright);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    
public:
    vector<string> addOperators(string num, int target) {
        set<int> targetSet;
        targetSet.insert(target);
        unordered_map<int, vector<string>> result = addOperatorsHelper(num, 0, num.length(), targetSet);
        return result[target];
    }
};
public class Solution {
    public List<String> addOperators(String num, int target) {
        List<String> res = new ArrayList<String>();
        if(num == null || num.length() == 0) return res;
        
        DFS(num, -target, 0, 0,"", res);
        return res;
        
    }
    
    public void DFS(String num, long sum, int k, int pre, String temp, List<String> res) {
        int len = num.length();
        if (sum == 0 && k == len) {
            res.add(temp);
            return;
        }
        long val = 0;
        for (int i = k; i < len; i ++) {
            val = val * 10 + num.charAt(i) - '0';
            //if(val > Integer.MAX_VALUE) {  // testcase: "21474836481" : 2147483647
                //return;
            //}
            if(k == 0) {
                DFS(num, sum + val, i + 1, (int)val, temp + String.valueOf(val), res);
            } else {
                DFS(num, sum + val, i + 1, (int)val, temp + "+" + String.valueOf(val), res);
                DFS(num, sum - val, i + 1, (int)(-val), temp + "-" + String.valueOf(val), res);
                DFS(num, sum - pre + val * pre, i + 1, (int)val * pre, temp + "*" + String.valueOf(val), res);
            }
            if(num.charAt(k) == '0') {
                return;
            }
            
            /*
            Wrong:["0+0+0","0+0-0","0+0*0","0-0+0","0-0-0","0-0*0","0*0+0","0*0-0","0*0*0","0+00",
            "0-00","0*00","00+0","00-0","00*0","000"]
            Correct:["0*0*0","0*0+0","0*0-0","0+0*0","0+0+0","0+0-0","0-0*0","0-0+0","0-0-0"]
            
            我们可以看到错误的结果中有0开头的字符串出现,明显这不是数字,所以我们要去掉这些情况,过滤方法也很简单,我们只要判断长度大于1且首字符是‘0’的字符串,将其滤去即可
            */
        }
    }
}



/*
"123"
6
"0"
0
"123"
1
"123"
15
""
1
*/

以上是关于java 282. Expression Add Operators.java的主要内容,如果未能解决你的问题,请参考以下文章

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

java 282. Expression Add Operators.java

282. Expression Add Operators

282. Expression Add Operators