leetcode_middle_34_241. Different Ways to Add Parentheses

本文介绍了一种使用递归方法解析算式并计算其所有可能结果的方法。通过将算式划分为多个区间,并利用递归求解每个区间内的结果,最终通过笛卡尔积的方式合并所有区间的计算结果。

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

题意:

给定一个算式(运算符号限为加减乘),用括号来限定其运算顺序,返回所有可能结果。

分析:

这个题拿着,举个例子研究下,比如 2 * 3 - 4 * 5,研究一下所加的括号,发现括号的大小,个数,位置等等与字符串长度的关系,但是很快发现这没什么用,这是一些数学规律,但是程序和数学是有很大区别的!程序有计算机帮助我们解决问题,所以我们应该从更宏观,更直接的层面和角度来思考如何解决一个问题。

我们的一个字符串,不同的划分,可以有很多种运算可能,我们要搜索(列举)出所有的可能,因为这个搜索不知道次数,只知道结束条件,很容易就想到递归。这时候找规律,发现可以分区间,第一个数一个括号,后面剩下的的一个括号, 前两个数一个括号,后面剩下的一个括号(两部分各有很多种可能,我们取其笛卡尔积即可)。而程序思维和数学思维的区别这里就体现了:程序思维是宏观的控制者的思维,我只关心划分了两个区间,就可以通过两个区间的笛卡尔积得到结果,而不关心每个区间怎么求,有什么微观的数学规律.......

所以不管是分治,动态规划,贪心,XX搜索,  递归等等,我认为其实都是一种宏观的核心的共通的算法思想,只是具体形式有区别。都是针对一个问题解决,一般的情况下的子问题怎么推广到问题的全局域。

所以我们重新整理思路:

我们要搜索一个字符串所有的组合方式,那么就是要找把这个字符串划分为两部分,两部分的组合方式的笛卡尔积。

采用递归的方式:

1. 递归结束条件:只剩下一个数(没有符号了),存储这个区间(只有一个数,最小的区间)的结果值。

2. 递归的每一层的遍历搜索(区间的划分):每一个运算符号都划分一次

3. 递归的每一个区间结果的合并,取取笛卡尔积

那么实现代码就很简单了:

public class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> list = new ArrayList<>();
        if(!(input.contains("+")||input.contains("-")||input.contains("*")))  //递归到底,只剩下一个单独的数字了
            list.add(Integer.valueOf(input));
            
        for(int i=0; i<input.length(); i++){  
        if(input.charAt(i)=='+' || input.charAt(i)=='-' || input.charAt(i)=='*'){  //对于一个字符串需要每个负号都划分一次
            String left = input.substring(0,i);                //划分,为两部分(三部分)
            char c = input.charAt(i);
            String right = input.substring(i+1);
                                                               //对于每一次划分
           List<Integer> a = diffWaysToCompute(left);         //取得左边区间的结果集(怎么取的不关心)
            List<Integer> b = diffWaysToCompute(right);        //取得右边区间的结果集(怎么取的不关心)
            for (int j : a) {                                  //对两个结果集求笛卡尔积
                    for (int k : b) {
                        if (c == '+') {
                            list.add(j + k);
                        } else if (c == '-') {
                            list.add(j - k);
                        } else if (c == '*') {
                            list.add(j * k);
                        }
                    }
                }
            }
        }
        return list;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值