算法初探LeetCode-为运算表达式设计优先级

95 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情

LeetCode241:为运算表达式设计优先级

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

生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104 。 示例 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]

思路分析

题目要求计算出所有加括号处理后的最终结果,括号的目的是优先计算,因此只需要维护(l,r)(l,r)(l,r)的表达式结果即可,递归地处理左右子问题,即可以得到原问题的解。 由于题目给出的是字符串,为了方便计算可以直接转换成list方便计算。在维护左右区间时是以运算符作为分界点,因此当区间(l,r),l=r时(l,r),l = r时(l,r),l=r时,那么此时区间只有一个数子,直接返回即可。等到左右区间都计算完后,按照乘法原理依次根据当前运算符计算结果即可。等到所有子问题都处理完,即得到原问题所有答案。

算法代码

List < String > exp = new ArrayList < > ();
public List < Integer > diffWaysToCompute(String expression) {
    int n = expression.length();
    //预处理成一个list方便计算
    for (int i = 0; i < n; i++) {
        if (Character.isDigit(expression.charAt(i))) {
            int j = i;
            while (j < n && Character.isDigit(expression.charAt(j))) j++;
            int x = Integer.parseInt(expression.substring(i, j));
            exp.add(String.valueOf(x));
            i = j - 1;
        } else exp.add(String.valueOf(expression.charAt(i)));
    }
    return dfs(0, exp.size() - 1);
}
public List < Integer > dfs(int l, int r) {
    List < Integer > tmp = new ArrayList < > ();
    if (l == r) {
        tmp.add(Integer.parseInt(exp.get(l)));
        return tmp;
    }
    for (int i = l + 1; i < r; i += 2) { //i每次移动两步,跳到下一个运算符上
        //以i(运算符)为分界点,递归处理左右
        List < Integer > left = dfs(l, i - 1), right = dfs(i + 1, r);
        //根据乘法原理,处理左右区间的数字
        for (int x: left) {
            for (int y: right) {
                int k = 0;
                if ("+".equals(exp.get(i))) {
                    k = x + y;
                } else if ("-".equals(exp.get(i))) {
                    k = x - y;
                } else k = x * y;
                tmp.add(k);
            }
        }

    }
    //最终答案 
    return tmp;
}

结果详情

Snipaste_2023-02-10_23-14-43.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!