[字符串 分治法] 241. 为运算表达式设计优先级 (分治法)

10 篇文章 0 订阅
3 篇文章 0 订阅

[字符串 分治法] 241. 为运算表达式设计优先级 (分治法)

241. 为运算表达式设计优先级

题目链接:https://leetcode-cn.com/problems/different-ways-to-add-parentheses/


分类:

  • 字符串:解析字符串上的数字,运算符、构造所有可能的括号组合;
  • 分治法:按运算符划分式子,返回子式的计算结果集合;
  • 动态规划:见参考链接的解法2.

在这里插入图片描述

思路:分治法 (递归实现)

问题分解:

例如:2*3-4*5 
  • 整个式子按第一个乘号可以划分成 2 和 3 - 4 * 5,
  • 第二个式子可以继续划分成:3和4 * 5 或 3 - 4和5,
  • 而4 * 5可以继续划分为4和5;3-4也可以继续划分为3和4.

这样可以将计算整个式子不断分割,大问题分解为小问题,划分过程可以用递归实现。

递归函数的返回值: 返回的是结果集合,例如3 - 4 * 5会返回(3-4) * 5 = -5和3 - (4 * 5) = -17。我们使用一个List<Integer> 来存放一个结果集合。

递归出口: 如果式子划分到只包含数字,则直接返回数字。如果式子不止有数字,就进入递归主体继续划分。

递归主体:遍历式子的每个字符,找出式子中的运算符,按该运算符将式子划分为两部分,这两部分继续进入下一层递归。

  • 式子的划分可以用substring来实现。

然后获取这两部分递归的返回值,得到的是划分的两个子式各自的结果集合,在这两个返回值集合里各选取一个元素,用当前运算符进行组合,得到的结果存入当前递归层维护的结果集合res中。

所有元素处理完毕后,返回当前递归层的结果集合res。

实现代码:

class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        //特殊用例:input为null或为""
        if(input == null || input.length() == 0) return new ArrayList<Integer>();
        List<Integer> res = new ArrayList<Integer>();
        //提取当前字符串的第一个数字
        int index = 0;
        while(index < input.length() && !isSign(input.charAt(index))) index++;
        //如果整个式子里只包含数字,则直接返回存放当前数字的列表
        if(index == input.length()){
            res.add(Integer.parseInt(input.substring(0, index)));
            return res;
        }
        //如果整个式子还包含运算符,则继续划分式子
        for(int i = 0; i < input.length(); i++){
            char ch = input.charAt(i);
            //如果当前字符是运算符,则按该运算符将式子划分成两部
            if(isSign(ch)){
                //划分的左右两部分继续进入下一层递归,返回各自的计算结果集合
                List<Integer> left = diffWaysToCompute(input.substring(0, i));
                List<Integer> right = diffWaysToCompute(input.substring(i + 1));
                //两集合内所有元素两两组合,按当前运算符计算最终结果,加入res
                for(int j = 0; j < left.size(); j++){
                    for(int k = 0; k < right.size(); k++){
                        res.add(caculate(left.get(j), right.get(k), ch));
                    }
                }
            }
        }
        return res;
    }

    //判断当前字符是不是运算符:是运算符返回true,不是则返回false
    public boolean isSign(char ch){
        if(ch == '+' || ch == '-' || ch == '*') return true;
        return false;
    }
    //返回两个int因子和char型符号的计算结果
    public int caculate(int num1, int num2, char sign){
        switch(sign){
            case '+':
                return num1 + num2;
            case '-':
                return num1 - num2;
            case '*':
                return num1 * num2;
            default:
                return -1;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值