Leetcode-Algorithm-Divide and Conquer-241
-
题目:
-
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 *.
(给定一个包含数字和算术符号的字符串,返回通过不同方法加上括号后得到的所有结果。有效的算术符号为+、-、*)
例子:
输入:
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
输出:
[−34,−14,−10,−10,10]
题解:
方法1:(分治法)
由题意可知,用不同的方法加上括号进行运算相当于算术符号以不同的顺序先后进行运算,需要把所有可能的顺序给找出来。因此可以循环遍历每个字符,当遇到一个算术符号时,再将算术符号左右两边的字符进行相同的递归操作。每一次左右递归操作完后,返回对应字符串可能产生的算术结果,然后根据当前的算术符号,以左右两边递归返回的结果作为当前算术符号的左右操作数,计算出所有的结果并返回。这样就能把所有的结果返回到最顶层的递归中了。递归结束条件是,当字符串只剩下数字时,返回结果就是该数字。
class Solution {
public:
vector<int> diffWaysToCompute(string input) {
vector<int> res;
for (string::size_type ix = 0; ix < input.size(); ++ix) {
char cur = input[ix];
if (cur == '+' || cur == '-' || cur == '*') {
vector<int> lres = diffWaysToCompute(input.substr(0, ix));
vector<int> rres = diffWaysToCompute(input.substr(ix+1));
for (vector<int>::size_type lix=0; lix < lres.size(); ++lix) {
for (vector<int>::size_type rix=0; rix < rres.size(); ++rix) {
if (cur == '+')
res.push_back(lres[lix] + rres[rix]);
else if (cur == '-')
res.push_back(lres[lix] - rres[rix]);
else
res.push_back(lres[lix] * rres[rix]);
}
}
}
}
if (res.empty())
res.push_back(atoi(input.c_str()));
return res;
}
};