题目:
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]
题意:
给定一个包含数字和运算符的字符串,返回所有对数字与运算符分组可能得到的计算结果。有效的运算符为 +, - 和 *。不同的方式加小括号。
思路:
分治法。将给定的字符串根据运算符分割成运算符前部分与后部分,之后将得到的子串再进行递归分割成两部分,以此递归。将每次递归调用产生的结果集进行两层循环组合,计算出不同组合的结果值,之后将结果值添加到List集合中返回。如果没有找到操作符,则说明传入的字符串中不包含运算符,为纯数字,则直接将传入的字符串转换为数字添加到List集合中即可。
代码:java版:10ms
public class Solution { public List<Integer> diffWaysToCompute(String input) { List<Integer> ret = new LinkedList<Integer>(); for (int i=0; i<input.length(); i++) { if (input.charAt(i) == '+' || input.charAt(i) == '-' || input.charAt(i) == '*') { //检测是否是运算符 String part1 = input.substring(0, i); //子串1 String part2 = input.substring(i+1); //子串2 List<Integer> part1Ret = diffWaysToCompute(part1); //将子串1递归调用函数本身 List<Integer> part2Ret = diffWaysToCompute(part2); //将子串2递归调用函数本身 for (Integer p1 : part1Ret) { //轮训两个子串的返回值,计算结果 for (Integer p2 : part2Ret) { int c = 0; switch (input.charAt(i)) { case '+': c = p1 + p2; break; case '-': c = p1 - p2; break; case '*': c = p1 * p2; break; } ret.add(c); //将每种组合的计算结果值添加到List中 } } } } if (ret.size() == 0) { //如果没有往List中添加值,说明没有运算符,则直接将字符串转换为整数添加进去。 ret.add(Integer.valueOf(input)); } return ret; } }分析可得,以上递归过程中做了大量的重复计算,维护一个map用来保存计算结果值,进行处理运算时,先查询map中是否已经有相应的部分,如果有,则直接取出,没有,则继续递归。利用空间换时间。
代码:C++版:4ms
class Solution { public: vector<int> diffWaysToCompute(string input) { unordered_map<string, vector<int>> dpMap; return computeWithDP(input, dpMap); } vector<int> computeWithDP(string input, unordered_map<string, vector<int>> &dpMap) { vector<int> result; int size = input.size(); for (int i=0; i<size; i++) { char cur = input[i]; if (cur == '+' || cur == '-' || cur == '*') { vector<int> result1, result2; string substr = input.substr(0, i); if (dpMap.find(substr) != dpMap.end()) result1 = dpMap[substr]; else result1 = computeWithDP(substr, dpMap); substr = input.substr(i+1); if (dpMap.find(substr) != dpMap.end()) result2 = dpMap[substr]; else result2 = computeWithDP(substr, dpMap); for (auto n1 : result1) { for (auto n2 : result2) { if (cur == '+') result.push_back(n1 + n2); else if (cur == '-') result.push_back(n1 - n2); else result.push_back(n1 * n2); } } } } if (result.empty()) result.push_back(atoi(input.c_str())); dpMap[input] = result; return result; } };