题目: 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 *
.
例子1:
Input: "2-1-1"
.
((2-1)-1) = 0
(2-(1-1)) = 2
Output: [0, 2]
解题思路:总体思路是运用分治算法思想进行解题。以‘+’、‘-’、‘*’符号为分割点将字符串分为左右两边,如例子第一个减号将式子“2-1-1”分成两半,左边为“2”,右边为“1-1”,左边的字符串只有数字没有符号,右边的式子仍然带有符号,右边的式子需要根据上述的方法再被分成两半,然后再计算结果。通过二叉树来说明会更加直观。
上图这个二叉树对应前面描述的过程。当然,例子中的式子还能构成另一颗二叉树,就是以第二个减号为树的根节点,将“2-1-1”,分成左结点“2-1”和右结点“1”,左结点“2-1”又可以“-”为父结点分为左结点“2”和右结点“1”。
而本题就等价与找出输入的式子能构成的所有二叉树并计算其结果返回到一个容器vector。
总的来说就是将式子以符号为分割点将式子分成左右两半,计算左边式子的所有可能值和右边式子的所有可能计算结果,再将左右两边的结果进行分割点符号的操作。左式和右式的所有可能计算结果是通过迭代计算得出的。
如有描述不当地方或任何建议,望各位积极提出~
代码如下:
class Solution {
public:
vector<int> diffWaysToCompute(string input) {
int flag = 0;
vector<int> left,right,ans(0);
if(input.empty()) return ans; //当输入为空时返回空vector
for(string::size_type i=0; i != input.size(); ++i)
if(!(isdigit(input[i]))) flag = 1;
if (flag == 0){
int temp=atoi(input.c_str());
ans.push_back(temp);
return ans; //当输入的字符串只有“数值”没有符号时返回字符串对应的数值
}
else{
for(string::size_type i = 0; i != input.size(); ++i){
if(input[i]=='+'||input[i]=='-'||input[i]=='*'){
string left_input,right_input;
left_input = input.substr(0,i);
right_input = input.substr(i+1,input.size()-i-1);
left = diffWaysToCompute(left_input);
right = diffWaysToCompute(right_input);
switch(input[i]){
case('+'):{
for (vector<int>::iterator liter = left.begin(); liter != left.end(); ++liter)
for (vector<int>::iterator riter = right.begin(); riter != right.end(); ++riter)
ans.push_back(*liter+*riter);
}break;
case('-'):{
for (vector<int>::iterator liter = left.begin(); liter != left.end(); ++liter)
for (vector<int>::iterator riter = right.begin(); riter != right.end(); ++riter)
ans.push_back(*liter-*riter);
}break;
case('*'):{
for (vector<int>::iterator liter = left.begin(); liter != left.end(); ++liter)
for (vector<int>::iterator riter = right.begin(); riter != right.end(); ++riter)
ans.push_back(*liter * *riter);
}break;
}
}
}
return ans;
}
}
};