leetcode241

241. Different Ways to Add Parentheses

package leetcode;

import java.util.ArrayList;
import java.util.List;

public class Solution241 extends Solution {
    @Override
    public void test() {
//        String input = "2-1-1";
        String input = "2*3-4-5";
        System.out.println(diffWaysToCompute(input));
    }

    public List<Integer> diffWaysToCompute(String input) {
        /*
             想法一:
             最开始的想法是迭代的计算每个符号的位置的值,即将第i个符号处两边的数字进行运算,
             并将运算后得到的值替代原先i个位置,且将i-1和i+1处的数字删去,这样就得到一个新
             的计算公式,然后进入下一次迭代。
             但这么做会出现重复的情况,如:2*3-4*5,正常答案是[-34, -14,-10,-10,10],但
             迭代后会出现两个-14,因为((2*3)-(4*5))会出现两次,分别为以2*3中的乘号为迭代
             起点和4*5中的乘号为迭代起点。
             所以该方法不可行。
             想法二:
             构造表达式树,以每个符号为树的根节点,左子树和右子树分别返回各自子表达式的所有可
             能情况的计算结果,然后根据根节点的符号组合左子树和右子树的结果。
         */
        if (input.length() < 3) {
            ArrayList<Integer> tmp = new ArrayList<>();
            if (input.contains("+") || input.contains("-") || input.contains("*")) {
                return tmp;
            } else {
                tmp.add(Integer.valueOf(input));
                return tmp;
            }
        }
        List<Integer> nums = new ArrayList<>(); //用来存放数字      [2,3,4,5]
        List<Character> operator = new ArrayList<>();//用来存放运算符  [*,-,*]
        int digit = 0;
        for(char c : input.toCharArray()){
            if (c >= '0' && c <= '9') {
                digit = digit * 10 + (c - '0');
            } else {
                nums.add(digit);
                digit = 0;
                operator.add(c);
            }
        }
        nums.add(digit);
        return helper(nums, operator, 0, operator.size()-1);
    }

    private List<Integer> helper(List<Integer> nums, List<Character> operator, int start, int end){
        if (end <= start) {
       // 如果只有一个运算符,就计算运算结果,并返回
int t = operator(operator.get(start), nums.get(start), nums.get(end+1)); List<Integer> res = new ArrayList<>(); res.add(t); return res; } List<Integer> res = new ArrayList<>(); List<Integer> left = null, right = null; for(int i=start; i<=end; i++){ if (i == start) { left = new ArrayList<>(); left.add(nums.get(start)); } else { left = helper(nums, operator, start, i-1); } if (i == end) { right = new ArrayList<>(); right.add(nums.get(end+1)); } else { right = helper(nums, operator, i + 1, end); } for (Integer l : left) { for (Integer r : right) { res.add(operator(operator.get(i), l, r)); } } } return res; } private int operator(char operator, int a, int b){ switch (operator){ case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; } return -1; } }

原文地址:https://www.cnblogs.com/liuyongyu/p/12532210.html