241. Different Ways to Add Parentheses[Medium]
Description
Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.
Example 1
Input: “2-1-1”.
((2-1)-1) = 0
(2-(1-1)) = 2
Output: [0, 2]
Example 2
Input: “2*3-4*5”
(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
Output: [-34, -14, -10, -10, 10]
Solution
分治法,以各个操作符(+、-、*)为分割,分别计算每个“小块”的结果,然后再进行全排列。自然而然想到递归,然而一开始并没有想好应该怎么设计分割后的计算结果并返回的接口,想着自己要增加函数。发现顺着题目编辑栏给出的函数原型考虑,返回一个int类型的vector就可以满足储存不同计算结果的需求。概括地说,对于每一个操作符,不停分隔左右边,然后相应返回不同情况下的result,相当于执行了【在不同位置上加上括号的要求】
Complexity analysis
时间复杂度O(Catalan(n)) 即O((2n)! / n!(n-1)!)
空间复杂度O(n),递归时系统栈空间的消耗
n为数操作符个数
这里是按网上说的,其实不会计算时间复杂度…有空再研究
Code
class Solution {
public:
vector<int> diffWaysToCompute(string input) {
vector<int> result;
char ch;
for (int i = 0; i < input.length(); i++) {
ch = input[i];
if (ch == '+' || ch == '*' || ch == '-') {
vector<int> left = diffWaysToCompute(input.substr(0, i));
vector<int> right = diffWaysToCompute(input.substr(i+1));
for (auto l : left) {
for (auto r : right) {
if (ch == '+') {
result.push_back(l+r);
} else if (ch == '-') {
result.push_back(l - r);
} else if (ch == '*') {
result.push_back(l*r);
}
}
}
}
}
if (result.empty()) {
result.push_back(atoi(input.c_str()));
}
return result;
}
};