题目地址:
https://leetcode.com/problems/different-ways-to-add-parentheses/
给定一个字符串 s s s,是一个中缀表达式,只含数字、加、减和乘法符号。允许在这个表达式里加括号改变该表达式的计算顺序。求所有可能得到的答案。注意,不需要去重。
思路是记忆化搜索。看到运算符的时候,可以考虑将其左右加上括号先算,算出两个答案之后,用两重循环,再按照当前运算符再算。如果不含运算符,那说明就是数字,那直接解析之返回。为了加速,可以用哈希表做记忆化。对每个表达式字符串,用哈希表存其所有取值,下次再遇到同样的表达式的时候直接调取记忆。代码如下:
class Solution {
public:
vector<int> diffWaysToCompute(string s) {
return dfs(s);
}
vector<int> dfs(string s) {
static unordered_map<string, vector<int>> mp;
if (mp.count(s)) return mp[s];
auto& v = mp[s];
bool isnum = true;
for (int i = 0; i < s.size(); i++)
if (!isdigit(s[i])) {
isnum = false;
auto l = dfs(s.substr(0, i)), r = dfs(s.substr(i + 1));
for (int x : l)
for (int y : r) {
if (s[i] == '+') v.push_back(x + y);
else if (s[i] == '-') v.push_back(x - y);
else v.push_back(x * y);
}
}
if (isnum) v.push_back(stoi(s));
return v;
}
};
时间复杂度与Catalan数有关,是 O ( C n ) O(C_n) O(Cn),空间也是 O ( C n ) O(C_n) O(Cn)。每个结果对应于一个所有节点组成complete binary tree的方案数。而每棵子树都做了记忆化,所以只会算一次。