241. 为运算表达式设计优先级(分治区间DP)
Posted mp-ui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了241. 为运算表达式设计优先级(分治区间DP)相关的知识,希望对你有一定的参考价值。
241. 为运算表达式设计优先级
难度中等399收藏分享切换为英文接收动态反馈
给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +
, -
以及 *
。
示例 1:
输入: "2-1-1"
输出: [0, 2]
解释:
((2-1)-1) = 0
(2-(1-1)) = 2
示例 2:
输入: "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
法一:分治(递归)
遍历expression,只要一碰到操作符就把他分成左右两段,并递归下去。递归之后也是如此。
class Solution {
public List<Integer> diffWaysToCompute(String expression) {
char[] cs = expression.toCharArray();
List<Integer> res = new ArrayList<>();
int cnt = 0; //操作符个数
for (int i = 0; i < cs.length; i++) {
if (cs[i] == '+' || cs[i] == '-' || cs[i] == '*') {
++cnt;
List<Integer> left = diffWaysToCompute(expression.substring(0, i));
List<Integer> right = diffWaysToCompute(expression.substring(i + 1));
for (Integer l : left) {
for (Integer r : right) {
if (cs[i] == '+') {
res.add(l + r);
} else if (cs[i] == '-') {
res.add(l - r);
} else {
res.add(l * r);
}
}
}
}
}
if(cnt == 0){
//纯数字
res.add(Integer.valueOf(expression));
}
return res;
}
}
运行结果:
法二:区间DP
思路和分治的思路类似,都是通过操作符将表达式分成左右两边。为了方便,我就预处理了一下将所有的数字和操作符分离了。
以为涉及到三维的集合,所以还是用cpp方便些。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//区间dp
class Solution {
public:
vector<int> diffWaysToCompute(string expression) {
vector<int> nums; //数字集合
vector<char> operations; //操作符集合
string token = "";
for(int i = 0;i < expression.size();++i){
if(expression[i] >= '0' && expression[i] <= '9'){
token += expression[i];
}else{
nums.push_back(atoi(token.c_str()));
operations.push_back(expression[i]);
token = "";
}
}
nums.push_back(atoi(token.c_str()));
int n = nums.size(); //一共多少个数字
//声明一个三维数组(实际上是二维的,第三维存的是我们要返回的结果)
vector<vector<vector<int>>> dp(n+1,vector<vector<int>>(n+1));
//区间长度为1的情况下
for(int i = 0;i < n;++i){
dp[i][i+1] = {nums[i]};
}
//区间长度从2到n一次递增
for(int size = 2;size <= n;++size){
for(int i = 0,j = size; j <= n;++i,++j){
for(int k = i + 1;k < n;++k){
char operation = operations[k-1];
for(auto it1 = dp[i][k].begin();it1!= dp[i][k].end();++it1){
for(auto it2 = dp[k][j].begin();it2 != dp[k][j].end();++it2){
if(operation == '+'){
dp[i][j].push_back(*it1 + *it2);
}else if(operation == '-'){
dp[i][j].push_back(*it1 - *it2);
}else{
dp[i][j].push_back(*it1 * *it2);
}
}
}
}
}
}
return dp[0][n];
}
};
运行结果:
以上是关于241. 为运算表达式设计优先级(分治区间DP)的主要内容,如果未能解决你的问题,请参考以下文章