282. Expression Add Operators

Description

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", "123"]
"232", 8 -> ["23+2", "2+32"]
"105", 5 -> ["10+5","10-5"]
"00", 0 -> ["0+0", "0-0", "0
0"]
"3456237490", 9191 -> []

Credits:
Special thanks to @davidtan1890 for adding this problem and creating all test cases.

Solution

DFS, time O(4 ^ n), space O(n)

这道题应该只能用穷举法去做,在每两个数字间隔的位置上,都有加减乘以及没有运算符四种选择。可是如何穷举呢?必须用DFS或者说backtrack才行。

几个值得注意的地方:

  • 无论是在最底层将path添加到结果集中,还是在上层拼接结果,应该都是可以的,下面的解法采用的是第一种,代码写起来更简洁;
  • 为什么需要target, eval, multi这几个变量呢?考虑连续乘法的情况,例如1 + 2 * 3 * 4 - 5,在计算到4的时候,做乘法它需要知道前面2 * 3的结果,在这里就用multi来表示。而eval在这里表示1 + 2 * 3的结果。这样最后只需要判断target == eval即可。
  • 特别需要注意的是,以0开头的数字是非法的!
  • 另外还需要注意中间结果可能会overflow,需要用long存储以避免这个问题。

总之是道挺难的题,查缺补漏了。

class Solution {
    public List addOperators(String num, int target) {
        List res = new ArrayList<>();
        if (num == null || num.isEmpty()) {
            return res;
        }
        
        dfs(num.toCharArray(), 0, target, 0, 0, "", res);
        return res;
    }
    
    public void dfs(char[] arr, int start, int target, long eval, long multi
                    , String path, List res) {
        if (start == arr.length) {
            if (target == eval) {
                res.add(path);
            }
            return;
        }
        
        long curr = 0;
        for (int i = start; i < arr.length; ++i) {
            if (i > start && arr[start] == '0') { // leading zeros in a number is illegal
                break;
            }
            
            curr = 10 * curr + arr[i] - '0';
            
            if (start == 0) {   // path is empty now, add curr by default
                dfs(arr, i + 1, target, eval + curr, curr, path + curr, res);
            } else {
                dfs(arr, i + 1, target, eval + curr, curr, path + "+" + curr, res);
                dfs(arr, i + 1, target, eval - curr, -curr, path + "-" + curr, res);
                dfs(arr, i + 1, target, eval - multi + multi * curr
                    , multi * curr, path + "*" + curr, res);
            }
        }        
    }
}

你可能感兴趣的:(282. Expression Add Operators)