LeetCode - 241. Different Ways to Add Parentheses 分治、dp

发布于 2024-06-03 11:11:04 字数 3880 浏览 16 评论 0

题目

解题思路

这个题目也有点分治的意思,但是主体还是记忆化递归,用记忆化递归写起来非常方便,思路也很清晰:

  • 递归函数,遍历当前字符串,只要有符号是 +-* 的就将整个字符串分开成两半;
  • 然后左边一半的字符串 lstr 去递归求出那个解的集合,右边的 rstr 也求出解的集合;
  • 最后关键的是当前的字符串的解是左和右的笛卡尔积
  • 然后记得记忆化;

Java 版本

class Solution {
    private HashMap<String, List<Integer>> map;

    public List<Integer> diffWaysToCompute(String input) {
        map = new HashMap<>();
        return helper(input);
    }

    private List<Integer> helper(String input) {
        if (map.containsKey(input))
            return map.get(input);
        List<Integer> res = new ArrayList<>();

        for (int i = 0; i < input.length(); i++) {

            char op = input.charAt(i);

            if (op == '*' || op == '+' || op == '-') {
                List<Integer> L = helper(input.substring(0, i));//求出左边
                List<Integer> R = helper(input.substring(i + 1));//求出右边

                for (Integer l : L) {// 左右两边笛卡尔积
                    for (Integer r : R) {
                        res.add(computer(l, r, op));
                    }
                }
            }
        }
        if (res.isEmpty()) {// 没有操作符 直接加入数字
            res.add(Integer.valueOf(input));
        }
        map.put(input, res);//记忆化
        return res;
    }

    private int computer(int a, int b, char op) {
        return op == '+' ? a + b : (op == '-' ? a - b : a * b);
    }
}

C++ 版本

class Solution {
public:
    vector<int> diffWaysToCompute(string input) {
        return helper(input);
    }
private:
    const vector<int>& helper(const string& input){ //使用 const+引用,即可防止随意修改,又不必建立拷贝
        if(mp.count(input))
            return mp[input];

        vector<int>res;
        for(int i = 0; i < input.length(); i++){ 
            char op = input[i];
            if(op == '+' || op == '-' || op == '*') {
                const string lstr = input.substr(0,i);
                const string rstr = input.substr(i+1);

                const vector<int>& L = helper(lstr);
                const vector<int>& R = helper(rstr);

                //笛卡尔积
                for(int l : L){ 
                    for(int r : R){ 
                        res.push_back(computer(l, r, op));
                    }
                }
            }
        }
        if(res.empty())
            res.push_back(stoi(input));
        return mp[input] = res;
    }
    int computer(int a, int b, char op){ 
        return op == '+' ? a + b : (op == '-' ? a - b : a * b);
    }
    unordered_map<string,vector<int>>mp; //使用无序 map(类似 HashMap,而不是 TreeMap)
};

Python 版本

class Solution:
    def diffWaysToCompute(self, input):
        if input.isdigit():  # 不同于 Java 版本,这里边界条件放在这里,之前那个是 res.isEmpty() 就加入数字
            return [int(input)]  # 转换成数字 -> 列表并返回
        res = []
        for i in range(len(input)):
            if input[i] in "+-*":
                L = self.diffWaysToCompute(input[:i])
                R = self.diffWaysToCompute(input[i+1:])

                for l in L:
                    for r in R:
                        res.append(self.computer(l, r, input[i]))

        return res

    def computer(self, a, b, op):
        if op == '+':
            return a + b
        elif op == '-':
            return a - b
        else:
            return a * b

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

苏别ゝ

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

emdigitizer10

文章 0 评论 0

残龙傲雪

文章 0 评论 0

奢望

文章 0 评论 0

微信用户

文章 0 评论 0

又爬满兰若

文章 0 评论 0

独孤求败

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文