分治算法详解:运算优先级

转载:https://labuladong.gitee.io/algo/di-san-zha-24031/jing-dian–a94a0/fen-zhi-su-65a39/

在这里插入图片描述
在这里插入图片描述

void sort(int[] nums, int lo, int hi) {
    int mid = (lo + hi) / 2;
    /****** 分 ******/
    // 对数组的两部分分别排序
    sort(nums, lo, mid);
    sort(nums, mid + 1, hi);
    /****** 治 ******/
    // 合并两个排好序的子数组
    merge(nums, lo, mid, hi);
}

在这里插入图片描述

力扣第 241 题「为运算表达式设计优先级」来讲讲什么是分治算法 :https://leetcode.cn/problems/different-ways-to-add-parentheses/

在这里插入图片描述
在这里插入图片描述

// 计算所有加括号的结果
List<Integer> diffWaysToCompute(String input);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// 定义:计算算式 input 所有可能的运算结果
List<Integer> diffWaysToCompute(String input);

在这里插入图片描述

List<Integer> diffWaysToCompute("(1 + 2 * 3) - (4 * 5)") {
    List<Integer> res = new LinkedList<>();
    /****** 分 ******/
    List<Integer> left = diffWaysToCompute("1 + 2 * 3");
    List<Integer> right = diffWaysToCompute("4 * 5");
    /****** 治 ******/
    for (int a : left)
        for (int b : right)
            res.add(a - b);

    return res;
}

在这里插入图片描述

List<Integer> diffWaysToCompute(String input) {
    List<Integer> res = new LinkedList<>();
    for (int i = 0; i < input.length(); i++) {
        char c = input.charAt(i);
        // 扫描算式 input 中的运算符
        if (c == '-' || c == '*' || c == '+') {
            /****** 分 ******/
            // 以运算符为中心,分割成两个字符串,分别递归计算
            List<Integer> 
                left = diffWaysToCompute(input.substring(0, i));
            List<Integer> 
                right = diffWaysToCompute(input.substring(i + 1));
            /****** 治 ******/
            // 通过子问题的结果,合成原问题的结果
            for (int a : left)
                for (int b : right)
                    if (c == '+')
                        res.add(a + b);
                    else if (c == '-')
                        res.add(a - b);
                    else if (c == '*')
                        res.add(a * b);
        }
    }
    // base case
    // 如果 res 为空,说明算式是一个数字,没有运算符
    if (res.isEmpty()) {
        res.add(Integer.parseInt(input));
    }
    return res;
}

在这里插入图片描述

// base case
// 如果 res 为空,说明算式是一个数字,没有运算符
if (res.isEmpty()) {
    res.add(Integer.parseInt(input));
}

在这里插入图片描述

// 备忘录
HashMap<String, List<Integer>> memo = new HashMap<>();

List<Integer> diffWaysToCompute(String input) {
    // 避免重复计算
    if (memo.containsKey(input)) {
        return memo.get(input);
    }
    /****** 其他都不变 ******/
    List<Integer> res = new LinkedList<>();
    for (int i = 0; i < input.length(); i++) {
        // ...
    }
    if (res.isEmpty()) {
        res.add(Integer.parseInt(input));
    }
    /***********************/

    // 将结果添加进备忘录
    memo.put(input, res);
    return res;
}

https://labuladong.gitee.io/algo/di-san-zha-24031/jing-dian–a94a0/fen-zhi-su-65a39/
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值