为运算表达式设计优先级

给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。

示例 1:

输入: "2-1-1"

输出: [0, 2]

解释:

((2-1)-1) = 0

(2-(1-1)) = 2

示例 2:

输入: "2*3-4*5"

输出: [-34, -14, -10, -10, 10]

解释:

(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

采用分治算法,分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同,求出子问题的解,就可得到原问题的解。那么针对本题,以操作符为分界,将字符串分解为较小的两个子字符串,然后依次对两个子字符串进行同样的划分,直到字符串中只含有数字。再根据操作符对两端的数字进行相应的运算。

由于原问题和子问题中操作符不止有一个,那么就需要在原问题和子问题中循环找到这个操作符,进行同样的划分:

 public class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> res = new ArrayList<Integer>();
for (int i=0; i<input.length(); i++) {
char ch = input.charAt(i);
if (ch == '+' || ch == '-' || ch == '*') {
List<Integer> left = diffWaysToCompute(input.substring(0,i));
List<Integer> right = diffWaysToCompute(input.substring(i+1,input.length()));
for (int l : left) {
for (int r : right) {
switch(ch) {
case '+' :
res.add(l+r);
break;
case '-' :
res.add(l-r);
break;
case '*' :
res.add(l*r);
break;
}
}
}
}
}
if (res.size() == 0) res.add(Integer.valueOf(input));
return res;
}
}

显然上述解法对子问题存在重复计算,效率不高,这里采用备忘录的自顶向下法,将子问题的计算结果保存下来,下次遇到同样的子问题就直接从备忘录中取出,而免去繁琐的计算,具体的做法是新建一个 hashmap,将子字符串放入 hashmap 中,对应的计算结果放入 value 中:

 public class Solution {
private HashMap<String, List<Integer>> hm = new HashMap<String, List<Integer>>();
public List<Integer> diffWaysToCompute(String input) {
if(hm.containsKey(input)) return hm.get(input);
List<Integer> res = new ArrayList<Integer>();
for (int i=0; i<input.length(); i++) {
char ch = input.charAt(i);
if (ch=='+' || ch=='-' || ch=='*')
for (Integer l : diffWaysToCompute(input.substring(0,i)))
for (Integer r : diffWaysToCompute(input.substring(i+1,input.length())))
if(ch=='+') res.add(l+r);
else if (ch == '-') res.add(l-r);
else res.add(l*r);
}
if (res.size() == 0) res.add(Integer.valueOf(input));
hm.put(input, res);
return res;
}
}

最新文章

  1. 做了一个sublime text插件
  2. com.panie 项目开发随笔_功能任务设计(2016.12.28)
  3. PHPCMS_V9 模型字段添加单文件上传功能
  4. jquery.validate.js插件使用
  5. Ninject之旅之六:Ninject约定
  6. asp.net webform中使用async,await实现异步操作
  7. js 小数取整的函数
  8. AtCoder Grand Contest 001
  9. 学渣也要搞 laravel(1)—— 安装篇
  10. U盘装centos7系统过程
  11. allocator 类
  12. Spring配置属性文件
  13. 商品规格笛卡尔积PHP
  14. linux 查看是否安装了MySQL
  15. win7 英文版 中文乱码
  16. 转:ECharts图表组件入门教程之Theme:ECharts图表的皮肤是什么?如何给图表换主题(皮肤)Theme?
  17. Nginx的文件夹的别名设计&amp;drupal简洁url
  18. Django学习---抽屉热搜榜分析【all】
  19. 六周psp
  20. arp_filter的验证,使用net namespace

热门文章

  1. 第02课 操作系统及Linux 系统介绍
  2. magento package
  3. java 环境变量的设置,备忘
  4. 当css样式表遇到层
  5. [转]ASP.NET MVC Bootstrap极速开发框架
  6. [转].NET 4 并行(多核)编程系列之二 从Task开始
  7. 前端编辑神器---sublime text2
  8. EmitMapper系列之一:EmitMapper入门
  9. logback日志异步打印
  10. 【学习笔记】深入理解js原型和闭包(13)——【作用域】和【上下文环境】