跳到主要内容

241.为运算表达式设计优先级

链接:241.为运算表达式设计优先级
难度:Medium
标签:递归、记忆化搜索、数学、字符串、动态规划
简介:给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, -  以及  * 。

题解 1 - typescript

  • 编辑时间:2021-10-25
  • 执行用时:88ms
  • 内存消耗:41.3MB
  • 编程语言:typescript
  • 解法介绍:对于每个操作符当作根节点计算。
function diffWaysToCompute(expression: string): number[] {
return dfs(expression);
function split(expression: string, idx: number) {
return [expression.substring(0, idx), expression.substring(idx + 1)];
}
function comp(num1: number, num2: number, op: string): number {
switch (op) {
case '+':
return num1 + num2;
case '-':
return num1 - num2;
case '*':
return num1 * num2;
default:
return num1 + num2;
}
}
function dfs(expression: string): number[] {
const n = expression.length;
const opIdxs: number[] = [];
for (let i = 0; i < n; i++) {
const ch = expression[i];
if (ch === '+' || ch === '-' || ch === '*') opIdxs.push(i);
}
if (opIdxs.length === 0) return [+expression];
const ans: number[] = [];
for (const idx of opIdxs) {
const [left, right] = split(expression, idx);
for (const num1 of dfs(left)) {
for (const num2 of dfs(right)) {
ans.push(comp(num1, num2, expression[idx]));
}
}
}
return ans;
}
}

题解 2 - cpp

  • 编辑时间:2022-07-01
  • 执行用时:8ms
  • 内存消耗:12.4MB
  • 编程语言:cpp
  • 解法介绍:分治。
class Solution {
public:
unordered_set<char> opset;
Solution() {
opset.insert('+');
opset.insert('-');
opset.insert('*');
}
vector<int> diffWaysToCompute(string expression) {
vector<int> ans, oplist;
int n = expression.size();
for (int i = 0; i < n; i++) {
if (opset.count(expression[i])) oplist.push_back(i);
}
if (oplist.size() == 0)
ans.push_back(toNum(expression));
else
dfs(expression, oplist, ans);
return ans;
}
int toNum(string &expression) {
int num = 0, n = expression.size(), i = 0;
while (i < n && !opset.count(expression[i]))
num = num * 10 + expression[i++] - '0';
return num;
}
void dfs(string &expression, vector<int> &oplist, vector<int> &ans) {
for (auto &idx : oplist) {
vector<int> llist = diffWaysToCompute(expression.substr(0, idx));
vector<int> rlist = diffWaysToCompute(
expression.substr(idx + 1, expression.size() - idx));
for (auto &num1 : llist) {
for (auto &num2 : rlist) {
switch (expression[idx]) {
case '+':
ans.push_back(num1 + num2);
break;
case '-':
ans.push_back(num1 - num2);
break;
case '*':
ans.push_back(num1 * num2);
break;
}
}
}
}
}
};

题解 3 - cpp

  • 编辑时间:2022-07-01
  • 执行用时:8ms
  • 内存消耗:12.4MB
  • 编程语言:cpp
  • 解法介绍:分治。
class Solution {
public:
unordered_set<char> opset;
Solution() {
opset.insert('+');
opset.insert('-');
opset.insert('*');
}
vector<int> diffWaysToCompute(string expression) {
vector<int> ans, oplist;
int n = expression.size();
for (int i = 0; i < n; i++) {
if (opset.count(expression[i])) oplist.push_back(i);
}
if (oplist.size() == 0)
ans.push_back(toNum(expression));
else
dfs(expression, oplist, ans);
return ans;
}
int toNum(string &expression) {
int num = 0, n = expression.size(), i = 0;
while (i < n && !opset.count(expression[i]))
num = num * 10 + expression[i++] - '0';
return num;
}
void dfs(string &expression, vector<int> &oplist, vector<int> &ans) {
for (auto &idx : oplist) {
vector<int> llist = diffWaysToCompute(expression.substr(0, idx));
vector<int> rlist = diffWaysToCompute(
expression.substr(idx + 1, expression.size() - idx));
for (auto &num1 : llist) {
for (auto &num2 : rlist) {
switch (expression[idx]) {
case '+':
ans.push_back(num1 + num2);
break;
case '-':
ans.push_back(num1 - num2);
break;
case '*':
ans.push_back(num1 * num2);
break;
}
}
}
}
}
};