IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 化繁为简的分治法:——(LC241(我太菜了做得头疼)) -> 正文阅读

[数据结构与算法]化繁为简的分治法:——(LC241(我太菜了做得头疼))

题目:

给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果

输入是一个字符串,表示数学表达式;输出是一个数组,存储所有不同的加括号结果。

题解:

顾名思义,分治问题由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子
问题,再将子问题进行处理合并,从而实现对原问题的求解。

例如:在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组,从长度为 1 的子数组开始,最终合成一个大数组。

自上而下的分治可以和 memoization 结合,避免重复遍历相同的子问题。如果方便推
导,也可以换用自下而上的动态规划方法求解。

利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达
式,再处理此运算符号

最巧妙的地方就是做一个预处理,把每个数字提前转为 int 然后存起来,同时把运算符也都存起来。这样的话我们就有了两个 list,一个保存了所有数字,一个保存了所有运算符。

2 * 3 - 4 * 5

存起来的数字是 numList = [2 3 4 5],

存起来的运算符是 opList = [*, -, *]。

dp[i][j]?也比较好定义了,含义是第?i?到第?j?个数字(从?0?开始计数)范围内的表达式的所有解。

举个例子,2 * 3 - 4 * 5 dp[1][3] 就代表第一个数字 3 到第三个数字 5 范围内的表达式 3 - 4 * 5 的所有解。

初始条件的话,也很简单了,就是范围内只有一个数字。

2 * 3 - 4 * 5

dp[0][0] = [2],dp[1][1] = [3],dp[2][2] = [4],dp[3][3] = [5]。

?

有了一个数字的所有解,然后两个数字的所有解就可以求出来。

有了两个数字的所有解,然后三个数字的所有解就和解法一求法一样。

把三个数字分成两部分,将两部分的解两两组合起来即可。

两部分之间的运算符的话,因为表达式是一个数字一个运算符,所以运算符的下标就是左部分最后一个数字的下标。
看下边的例子。

2 * 3 - 4 * 5
存起来的数字是 numList = [2 3 4 5],
存起来的运算符是 opList = [*, -, *]。

假设我们求 dp[1][3]
也就是计算 3 - 4 * 5 的解
分成 3 和 4 * 5 两部分,3 对应的下标是 1 ,对应的运算符就是 opList[1] = '-' 。
也就是计算 3 - 20 = -17
? ??
分成 3 - 4 和 5 两部分,4 的下标是 2 ,对应的运算符就是 opList[2] = '*'。
也就是计算 -1 * 5 = -5
? ??
所以 dp[1][3] = [-17 -5]

四个、五个... 都可以分成两部分,然后通过之前的解求出来。

直到包含了所有数字的解求出来,假设数字总个数是?ndp[0][n-1]?就是最后返回的了。

class Solution {
 public List<Integer> diffWaysToCompute(String input) {
    List<Integer> numList = new ArrayList<>();
    List<Character> opList = new ArrayList<>();
    char[] array = input.toCharArray();
    int num = 0;
    for (int i = 0; i < array.length; i++) {
        if (isOperation(array[i])) {
            numList.add(num);
            num = 0;
            opList.add(array[i]);
            continue;
        }
        num = num * 10 + array[i] - '0';
    }
    numList.add(num);
    int N = numList.size(); // 数字的个数

    // 一个数字
    ArrayList<Integer>[][] dp = (ArrayList<Integer>[][]) new ArrayList[N][N];
    for (int i = 0; i < N; i++) {
        ArrayList<Integer> result = new ArrayList<>();
        result.add(numList.get(i));
        dp[i][i] = result;
    }
    // 2 个数字到 N 个数字
    for (int n = 2; n <= N; n++) {
        // 开始下标
        for (int i = 0; i < N; i++) {
            // 结束下标
            int j = i + n - 1;
            if (j >= N) {
                break;
            }
            ArrayList<Integer> result = new ArrayList<>();
            // 分成 i ~ s 和 s+1 ~ j 两部分
            for (int s = i; s < j; s++) {
                ArrayList<Integer> result1 = dp[i][s];
                ArrayList<Integer> result2 = dp[s + 1][j];
                for (int x = 0; x < result1.size(); x++) {
                    for (int y = 0; y < result2.size(); y++) {
                        // 第 s 个数字下标对应是第 s 个运算符
                        char op = opList.get(s);
                        result.add(caculate(result1.get(x), op, result2.get(y)));
                    }
                }
            }
            dp[i][j] = result;

        }
    }
    return dp[0][N-1];
}

private int caculate(int num1, char c, int num2) {
    switch (c) {
        case '+':
            return num1 + num2;
        case '-':
            return num1 - num2;
        case '*':
            return num1 * num2;
    }
    return -1;
}

private boolean isOperation(char c) {
    return c == '+' || c == '-' || c == '*';
}


}


总结记录来源:力扣(LeetCode)(一位大神的题解)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-08 11:34:33  更:2021-08-08 11:50:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:16:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码