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

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

现在有一个字符串形式的算式,求该算式在任意位置加上任意数量的括号后能够得出的所有可能的值。

思路与算法

这是经典的分治法。我们将算式从一个操作符的位置分割开,并分别得出左边和右边算式所有可能的值。再将左右的值分别按照操作符进行计算。这里通过递归实现。

    public List diffWaysToCompute(String input) {
        return diffWaysToCompute(input, 0, input.length());
    }
    
    public List diffWaysToCompute(String input, int startIndex, int endIndex){
        boolean isDigit = true;
        List result = new ArrayList();
        for(int i = startIndex ; i leftValue = diffWaysToCompute(input, startIndex, i);
                List rightValue = diffWaysToCompute(input, i+1, endIndex);
                result.addAll(compute(leftValue, rightValue,cur));
            }
        }
        if(isDigit){
            result.add(Integer.parseInt(input.substring(startIndex, endIndex)));
        }
        return result;
    }
    
    public List compute(List leftValue, List 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 add(List leftValue, List rightValue){
        List result = new ArrayList();
        for(int left : leftValue){
            for(int right : rightValue){
                result.add(left + right);
            }
        }
        return result;
    }
    
    public List minus(List leftValue, List rightValue){
        List result = new ArrayList();
        for(int left : leftValue){
            for(int right : rightValue){
                result.add(left - right);
            }
        }
        return result;
    }
    
    public List multiply(List leftValue, List rightValue){
        List result = new ArrayList();
        for(int left : leftValue){
            for(int right : rightValue){
                result.add(left * right);
            }
        }
        return result;
    }

提高性能的方法是通过Map实现缓存。将已经遍历过的结果存入缓存中,如果碰到重复的计算式,就可以直接获取其所有可能的值。

    Map> cache = new HashMap>();
    public List diffWaysToCompute_withCache(String input){
        if(cache.containsKey(input)) return cache.get(input);
        List result = new ArrayList();
        boolean isDigit = true;
        for(int i = 0 ; i leftValues = diffWaysToCompute_withCache(input.substring(0, i));
                List 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;
                        }
                    }
                }
            }
        }
        if(isDigit){ result.add(Integer.parseInt(input));}
        cache.put(input, result);
        return result;
    }

leetcode241. Different Ways to Add Parentheses_第1张图片
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~

你可能感兴趣的:(leetcode,java,缓存,divide-conquer)