算法学习100天——17 分治思想

题目地址(241. 为运算表达式设计优先级)

https://leetcode-cn.com/problems/different-ways-to-add-parentheses/

题目描述

给你一个由数字和运算符组成的字符串 expression ,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以 按任意顺序 返回答案。

示例 1:
输入:expression = "2-1-1"
输出:[0,2]
解释:
((2-1)-1) = 0 
(2-(1-1)) = 2

示例 2:
输入:expression = "2*3-4*5"
输出:[-34,-14,-10,-10,10]
解释:
(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

提示:
1 <= expression.length <= 20
expression 由数字和算符 '+'、'-' 和 '*' 组成。
输入表达式中的所有整数值在范围 [0, 99] 

思路

  1. 按照运算符号将表达式分开
  2. 分开后的表达式,分别计算两边的子表达式的值,结果存数组
  3. 遍历两边的数组,互相按照当前运算法计算,得到不同的结果
  4. 递归

Java Code

class Solution {
    public List<Integer> diffWaysToCompute(String expression) {
        // 分治法,将一个符号两边分开处理,计算出所有的子表达式的值存放进数组,然后交叉相乘
        return divideAndCalculate(expression);
    }

    public List<Integer> divideAndCalculate(String expression){
        List<Integer> res = new ArrayList<>();
        // 递归出口
        if(checkOnlyOneNum(expression)){
            int num = 0;
            for(char i : expression.toCharArray()){
                num = num * 10 + (i - '0');
            }
            res.add(num);
            return res;
        }

        // 根据符号,将符号两边的表达式分开,并获取所有子表达式的值,然后交叉计算
        for(int i = 0; i < expression.length(); i++){
            // 一直遍历,直到遇到算术符号
            if(checkIsOperator(expression.charAt(i))){
                List<Integer> left = divideAndCalculate(expression.substring(0, i));
                List<Integer> right = divideAndCalculate(expression.substring(i + 1));
                for(int l : left){
                    for(int r : right){
                        res.add(calculate(l, expression.charAt(i), r));
                    }
                }
            }
        }
        return res;
    }

    // 计算
    private Integer calculate(int l, char charAt, int r) {
        switch (charAt){
            case '+' : return l + r;
            case '-' : return l - r;
            case '*' : return l * r;
            default: return 0;
        }
    }

    // 判断当前表达式是否只有一个数了
    private boolean checkOnlyOneNum(String expression){
        for(char c : expression.toCharArray()){
            if(checkIsOperator(c)){
                return false;
            }
        }
        return true;
    }

    // 判断是不是操作符
    private boolean checkIsOperator(char c){
        return c == '+' || c == '-' || c == '*';
    }
}

posted @ 2022-03-21 15:41  浪漫主义程序员  阅读(30)  评论(0编辑  收藏  举报