[LeetCode] 241. Different Ways to Add Parentheses

Given a string expression of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. You may return the answer in any order.

The test cases are generated such that the output values fit in a 32-bit integer and the number of different results does not exceed 104.

Example 1:

Input: expression = "2-1-1"
Output: [0,2]
Explanation:
((2-1)-1) = 0 
(2-(1-1)) = 2

Example 2:

Input: expression = "2*3-4*5"
Output: [-34,-14,-10,-10,10]
Explanation:
(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

Constraints:

  • 1 <= expression.length <= 20
  • expression consists of digits and the operator '+''-', and '*'.
  • All the integer values in the input expression are in the range [0, 99].

为运算表达式设计优先级。

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

生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/different-ways-to-add-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题意是给一个以字符串表示的运算表达式,请为其添加括号,展示出所有可能的解。运算符号只有+,-,*。

思路是分治法,按每个操作符把input字符串进行分割,分别计算操作符两边的部分的结果。在实际操作的过程中,不需要真的添加括号,而是会通过分治的办法以达到括号能实现的运算优先级的目的。具体的思路是,遍历 input 字符串,每当遇到一个运算符号,就把这个符号的左边和右边分开,接着往下分治计算。在分治后的两个 list 中,挑出两个数字两两计算。最后把计算结果加入最后的 list。

注意一个 corner case 是 input 字符串里没有任何操作符,那么我们就把字符串转成数字输出即可。

时间 - O(2^n), n 是操作符的个数。这里回答卡特兰数也可以。

空间 - O(2^n), n 是操作符的个数。这里回答卡特兰数也可以。

Java实现

 1 class Solution {
 2     public List<Integer> diffWaysToCompute(String expression) {
 3         List<Integer> res = new ArrayList<>();
 4         // corner case
 5         if (expression == null || expression.length() == 0) {
 6             return res;
 7         }
 8         
 9         // corner case, when we only have numbers in the expression
10         int num = 0;
11         int index = 0;
12         while (index < expression.length() && !isOperator(expression.charAt(index))) {
13             num = num * 10 + expression.charAt(index) - '0';
14             index++;
15         }
16         if (index == expression.length()) {
17             res.add(num);
18             return res;
19         }
20         
21         // normal case
22         for (int i = 0; i < expression.length(); i++) {
23             if (isOperator(expression.charAt(i))) {
24                 List<Integer> list1 = diffWaysToCompute(expression.substring(0, i));
25                 List<Integer> list2 = diffWaysToCompute(expression.substring(i + 1));
26                 for (int num1 : list1) {
27                     for (int num2 : list2) {
28                         char op = expression.charAt(i);
29                         res.add(calculate(num1, op, num2));
30                     }
31                 }
32             }
33         }
34         return res;
35     }
36     
37     private int calculate(int num1, char op, int num2) {
38         switch (op) {
39             case '+':
40                 return num1 + num2;
41             case '-':
42                 return num1 - num2;
43             case '*':
44                 return num1 * num2;
45         }
46         return -1;
47     }
48     
49     private boolean isOperator(char c) {
50         if (c == '+' || c == '-' || c == '*') {
51             return true;
52         }
53         return false;
54     }
55 }

 

LeetCode 题目总结

posted @ 2020-07-11 11:11  CNoodle  阅读(164)  评论(0编辑  收藏  举报