Leetcode_241_为运算表达式设计优先级_记忆化dfs

本文介绍了一种使用深度优先搜索(DFS)算法解决数学表达式计算问题的方法。通过将问题分解为子问题并利用记忆化搜索减少重复计算,有效地提高了计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将问题递归成子问题
对于a * b - c
可以先以运算符为分界
比如以-号为分界
-号左侧a * b
-号右侧c
所以总的结果中包含(a * b) - c
a * b的结果同样递归
以此类推

在运算过程中有大量的中间态结果是重复需要的,所以用记忆化dfs的方式即可

class Solution {
    List<Integer> elements = new ArrayList<>();
    int           n;

    // dfs[i][j] 是 从i到j 的所有结果的集合
    List<Integer>[][] dfs;

    public List<Integer> diffWaysToCompute(String expression) {
        int len = expression.length();
        int temp = 0;
        for (int i = 0; i < len; i++) {
            char c = expression.charAt(i);
            if (!Character.isDigit(c)) {
                if (c == '+') {
                    elements.add(-1);
                } else if (c == '-') {
                    elements.add(-2);
                } else if (c == '*') {
                    elements.add(-3);
                }
            } else {
                temp *= 10;
                temp += Integer.parseInt(String.valueOf(c));
                if (i == len - 1 || !Character.isDigit(expression.charAt(i + 1))) {
                    elements.add(temp);
                    temp = 0;
                }
            }
        }

        n = elements.size();
        dfs = new List[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                dfs[i][j] = new ArrayList<>();
            }
            dfs[i][i].add(elements.get(i));
        }

        return dfs(0, n - 1);
    }

    List<Integer> dfs(int start, int end) {
        if (dfs[start][end].isEmpty()) {
            for (int i = start + 1; i <= end; i++) {
                addResult(start, end, elements.get(i), i);
            }
        }
        return dfs[start][end];
    }

    void addResult(int start, int end, int number, int index) {
        if (elements.get(index) < 0) {
            List<Integer> left = dfs(start, index - 1);
            List<Integer> right = dfs(index + 1, end);
            for (Integer l : left) {
                for (Integer r : right) {
                    if (number == -1) {
                        dfs[start][end].add(l + r);
                    } else if (number == -2) {
                        dfs[start][end].add(l - r);
                    } else if (number == -3) {
                        dfs[start][end].add(l * r);
                    }
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值