LC241 Different Ways to Add Parentheses (高级dp,1 ms)

LC241 Different Ways to Add Parentheses

这题贴出来的原因:这题的动态规划解法,是我自己想出来的,我感觉这题的动态规划算是有点难度了(普通的二维dp的进阶进阶版本),而且我做到了 1 ms beats 99.93%,37.3 mb beats 96.98%。还是很有成就感的。

动态规划

动态规划虽然代码多了,逻辑复杂了,但是时间空间都缩减了很多。


List<Integer> data = new ArrayList<>();
    List<Character> ops = new ArrayList<>();
    public List<Integer> diffWaysToCompute(String input) {
        int last = 0;
        // update data and ops
        for (int i = 0; i < input.length(); ++i) {
            char c = input.charAt(i);
            if (c == '-' || c == '+' || c == '*') {
                ops.add(c);
                data.add(Integer.valueOf(input.substring(last, i)));
                last = i + 1;
            }
        }
        data.add(Integer.valueOf(input.substring(last)));

        int n = data.size();
        List<Integer>[][] dp = new List[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                dp[i][j] = new ArrayList<>();

        for (int i = n; i >= 0; --i)
            for (int j = i; j < n; ++j)
                doThing(dp, i, j);

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

    private List<Integer> doThing(List<Integer>[][] dp, int i, int j) {
        if (dp[i][j].size() > 0)
            return dp[i][j];
        if (j == i) {
            dp[i][j].add(data.get(i));
        } else if (j - i == 1) {
            dp[i][j].add(cal(i, j));
        } else {
            for (int k = i; k < j; ++k) {
                List<Integer> left = doThing(dp, i, k);
                List<Integer> right = doThing(dp, k + 1, j);
                for (int l : left) {
                    for (int r : right) {
                        dp[i][j].add(cal(l, r, k));
                    }
                }
            }
        }
        return dp[i][j];
    }

    public int cal(int i, int j) {
        switch (ops.get(i)) {
            case '+' : return data.get(i) + data.get(j);
            case '-' : return data.get(i) - data.get(j);
            case '*' : return data.get(i) * data.get(j);
            default: return -1;
        }
    }

    public int cal(int i, int j, int k) {
        switch (ops.get(k)) {
            case '+' : return i + j;
            case '-' : return i - j;
            case '*' : return i * j;
            default: return -1;
        }
    }

分治法

public List<Integer> diffWaysToCompute(String input) {
        List<Integer> ways = new ArrayList<>();
        for (int i = 0; i < input.length(); ++i) {
            char c = input.charAt(i);
            if (c == '+' || c == '-' || c == '*') {
                List<Integer> left = diffWaysToCompute(input.substring(0, i));
                List<Integer> right = diffWaysToCompute(input.substring(i + 1));
                for (int l : left) {
                    for (int r : right)
                        if (c == '+') {
                            ways.add(r + l);
                            break;
                        }
                        else if (c == '-') {
                            ways.add(l - r);
                            break;
                        }
                        else {
                            ways.add(l * r);
                            break;
                        }
                }
            }
        }
        if (ways.isEmpty())
            ways.add(Integer.valueOf(input));
        return ways;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值