Different Ways to Add Parentheses

Problem

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".

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


Example 2
Input: "2*3-4*5"

(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
Output: [-34, -14, -10, -10, 10]

Solution

Left and Right Recursive Solution

public class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            if (ch == '+' || ch == '-' || ch == '*') {
                String left = input.substring(0, i), right = input.substring(i + 1);
                List<Integer> leftRes = diffWaysToCompute(left), rightRes = diffWaysToCompute(right);
                for (int num1 : leftRes) {
                    for (int num2 : rightRes) {
                        if (ch == '+') res.add(num1 + num2);
                        else if (ch == '-') res.add(num1 - num2);
                        else if (ch == '*') res.add(num1 * num2);
                    }
                }
            }
        }
        if (res.size() == 0) res.add(Integer.parseInt(input)); //Last recursion returns 
        return res;
    }
}

Optimal Solution of Above Using Map

public class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        return helper(input, new HashMap<>());
    }

    private List<Integer> helper(String input, Map<String, List<Integer>> map) {
        if (map.containsKey(input)) return map.get(input);

        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            if (ch == '+' || ch == '-' || ch == '*') {
                String left = input.substring(0, i), right = input.substring(i + 1);
                List<Integer> leftRes = diffWaysToCompute(left), rightRes = diffWaysToCompute(right);
                for (int num1 : leftRes) {
                    for (int num2 : rightRes) {
                        if (ch == '+') res.add(num1 + num2);
                        else if (ch == '-') res.add(num1 - num2);
                        else if (ch == '*') res.add(num1 * num2);
                    }
                }
            }
        }
        if (res.size() == 0) res.add(Integer.parseInt(input));
        map.put(input, res);
        return res;
    }
}

Analysis

To get different result, we need to think about the sequence of calculating the operations
Then it becomes a permutation of sequences of calculating the operations
To get all possibles, we have a for loop from 0 until the end of input
If we have an operation char at current index, we need its left and right operands
We construct them by recursively calling the method with input.substring(0, i) and input.substring(i + 1)
Then we collect different result using two nested for loops calculating value based on the operator
At the end of recursion, we will have only number value hence we simply parse and add it to our res
Notice that we can use a HashMap to optimize our recursion's calls

results matching ""

    No results matching ""