「LeetCode」241-为运算表达式设计优先级

123 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

一.题目:

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

示例 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]

二、思路分析:

这道题主要是利用了分治算法的思路,我们需要将原问题分解为小规模的子问题,然后根据子问题的结果去构造原问题的答案。因为题目给定算式,我们需要在算式的基础上加括号来进行运算,所以可以利用分治的方法去解决问题,具体的步骤为:

  • 我们需要确定如何分割,即利用运算符进行分割,我们找到运算符的时候将左右两边分开来,然后分别进行运算,然后根据得出的结果进行合并即可。
  • 因为分治算法需要用到递归,一旦遇到递归我们就必须要有个base case来结束递归,我们的判断理由是对res进行判断,如果为空就说明是一个数字没有运算符,直接进行化整即可。 举例(1 + 2 * 3) - (4 * 5),利用-分隔,左边就有两个形式:
  1. (1) + (2 * 3) = 7
  2. (1 + 2) * (3) = 9 右边就是4 * 5,推导结果即可。

三、代码:

/**
 * @param {string} expression
 * @return {number[]}
 */
var diffWaysToCompute = function(expression) {
    let res = []
    for(let i=0 ; i<expression.length ; i++){
        if(expression[i] == '+' || expression[i] == '-' || expression[i] == '*'){
            let left = diffWaysToCompute(expression.substring(0,i)) 
            let right = diffWaysToCompute(expression.substring(i+1)) 
            for(let a of left){
                for(let b of right){
                    if(expression[i] == '+'){
                        res.push(a+b)
                    }
                    if(expression[i] == '-'){
                        res.push(a-b)
                    }
                    if(expression[i] == '*'){
                        res.push(a*b)
                    }
                }
            }
        }
    }
    //base case 
    if(!res.length){
        res.push(parseInt(expression))
    }
    return res
};

四、总结:

通过这道题我们知道了对于这种原问题可以进行多个子问题求解最后进行合并的步骤的时候,就是利用了分治的思想对问题进行求解的,所以以后遇到类似问题,我们就可以直接利用分治进行求解,但是需要注意设定它的base case