Difficulty: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
我的思路
采用Divide-and-conquer的思想,将一个算式以运算符为分割处,分割成若干个算式。由于算式中可能有多个运算符,因此可以在不同地方进行分割,因而计算出不同的结果(返回一个数组,该数组包含所有的运算结果)。若算式中没有运算符,则该算式为一个整数,该整数就是一个结果(返回一个数组,该数组只包含一个整数)。
将该思路转为代码,就是调用递归函数,不断将算式分割,计算出每一部分的子算式结果,再返回。
代码
Accepted, 3ms
class Solution {
public:
vector<int> diffWaysToCompute(string input) { // 返回一个算式的所有结果
// res是返回结果,res1和res2分别存储算式以运算符号为界的左右两边的所有结果
vector<int> res, res1, res2;
int len = input.length();
for (int i = 0; i < len; ++i) {
if (!('0' <= input[i] && input[i] <= '9')) {
// 分割,递归调用函数;返回算式左半部分的所有不同结果
res1 = diffWaysToCompute(input.substr(0, i));
// 返回算式右半部分的所有不同结果
res2 = diffWaysToCompute(input.substr(i + 1, len));
switch (input[i]) { // 将算式两边所有不同结果算一遍
case '+':
for (int &n1 : res1) {
for (int &n2 : res2) res.push_back(n1 + n2);
}
break;
case '-':
for (auto &n1 : res1) {
for (auto &n2 : res2) res.push_back(n1 - n2);
}
break;
default:
for (auto &n1 : res1) {
for (auto &n2 : res2) res.push_back(n1 * n2);
}
break;
}
}
}
// 若算式没有运算符号,则返回一个整数
if (res.empty()) res.push_back(stoi(input));
return res;
}
};