开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
LeetCode241:为运算表达式设计优先级
给你一个由数字和运算符组成的字符串 expression
,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以 按任意顺序 返回答案。
生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104
。
示例 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]
思路分析
题目要求计算出所有加括号处理后的最终结果,括号的目的是优先计算,因此只需要维护(l,r)(l,r)(l,r)的表达式结果即可,递归地处理左右子问题,即可以得到原问题的解。 由于题目给出的是字符串,为了方便计算可以直接转换成list方便计算。在维护左右区间时是以运算符作为分界点,因此当区间(l,r),l=r时(l,r),l = r时(l,r),l=r时,那么此时区间只有一个数子,直接返回即可。等到左右区间都计算完后,按照乘法原理依次根据当前运算符计算结果即可。等到所有子问题都处理完,即得到原问题所有答案。
算法代码
List < String > exp = new ArrayList < > ();
public List < Integer > diffWaysToCompute(String expression) {
int n = expression.length();
//预处理成一个list方便计算
for (int i = 0; i < n; i++) {
if (Character.isDigit(expression.charAt(i))) {
int j = i;
while (j < n && Character.isDigit(expression.charAt(j))) j++;
int x = Integer.parseInt(expression.substring(i, j));
exp.add(String.valueOf(x));
i = j - 1;
} else exp.add(String.valueOf(expression.charAt(i)));
}
return dfs(0, exp.size() - 1);
}
public List < Integer > dfs(int l, int r) {
List < Integer > tmp = new ArrayList < > ();
if (l == r) {
tmp.add(Integer.parseInt(exp.get(l)));
return tmp;
}
for (int i = l + 1; i < r; i += 2) { //i每次移动两步,跳到下一个运算符上
//以i(运算符)为分界点,递归处理左右
List < Integer > left = dfs(l, i - 1), right = dfs(i + 1, r);
//根据乘法原理,处理左右区间的数字
for (int x: left) {
for (int y: right) {
int k = 0;
if ("+".equals(exp.get(i))) {
k = x + y;
} else if ("-".equals(exp.get(i))) {
k = x - y;
} else k = x * y;
tmp.add(k);
}
}
}
//最终答案
return tmp;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!