# Leetcode 241. Different Ways to Add Parentheses

Time：2019-8-13

## Topic Requirements

``````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]``````

Now there is an expression in the form of a string to find all possible values that can be obtained by adding any number of parentheses at any position.

## Thoughts and Algorithms

This is the classic divide and conquer method. We separate the expression from the position of an operator and derive all possible values of the left and right operators, respectively. Then the left and right values are calculated according to the operator respectively. This is achieved by recursion.

``````    public List<Integer> diffWaysToCompute(String input) {
return diffWaysToCompute(input, 0, input.length());
}

public List<Integer> diffWaysToCompute(String input, int startIndex, int endIndex){
boolean isDigit = true;
List<Integer> result = new ArrayList<Integer>();
for(int i = startIndex ; i<endIndex ; i++){
char cur = input.charAt(i);
if(cur == '+' || cur == '-' || cur=='*' ){
isDigit = false;
List<Integer> leftValue = diffWaysToCompute(input, startIndex, i);
List<Integer> rightValue = diffWaysToCompute(input, i+1, endIndex);
}
}
if(isDigit){
}
return result;
}

public List<Integer> compute(List<Integer> leftValue, List<Integer> rightValue, char operator){
switch(operator){
case '+' : return add(leftValue, rightValue);
case '-' : return minus(leftValue, rightValue);
case '*' : return multiply(leftValue, rightValue);
}
return new ArrayList<>();
}

public List<Integer> add(List<Integer> leftValue, List<Integer> rightValue){
List<Integer> result = new ArrayList<Integer>();
for(int left : leftValue){
for(int right : rightValue){
}
}
return result;
}

public List<Integer> minus(List<Integer> leftValue, List<Integer> rightValue){
List<Integer> result = new ArrayList<Integer>();
for(int left : leftValue){
for(int right : rightValue){
}
}
return result;
}

public List<Integer> multiply(List<Integer> leftValue, List<Integer> rightValue){
List<Integer> result = new ArrayList<Integer>();
for(int left : leftValue){
for(int right : rightValue){
}
}
return result;
}``````

The way to improve performance is to implement caching through Map. The results that have been traversed are stored in the cache, and all possible values can be obtained directly if there are duplicate formulas.

``````    Map<String, List<Integer>> cache = new HashMap<String, List<Integer>>();
public List<Integer> diffWaysToCompute_withCache(String input){
if(cache.containsKey(input)) return cache.get(input);
List<Integer> result = new ArrayList<Integer>();
boolean isDigit = true;
for(int i = 0 ; i<input.length() ; i++){
int cur = input.charAt(i);
if(cur == '+' || cur == '-' || cur == '*'){
isDigit = false;
List<Integer> leftValues = diffWaysToCompute_withCache(input.substring(0, i));
List<Integer> rightValues = diffWaysToCompute_withCache(input.substring(i+1));
for(Integer left : leftValues){
for(Integer right : rightValues){
switch(cur){
case '+' : result.add(left + right); break;
case '-' : result.add(left - right); break;
case '*' : result.add(left * right); break;
}
}
}
}
}