Expression Add Operators -- leetcode
2015-10-14 10:19
218 查看
Given a string that contains only digits
to add binary operators (not unary)
or
Examples:
算法一,
每得到一个新的整数,对其进行+, -, *三种运算。
使用dfs递归,免去重复计算。
此处使用sum, mul两个变量记录中间结果。 sum 存储累加和, mul 存储乘积结果。
之所以用两个,是基于如下情况:
1. 当我们在一个整数前添加+号时, 此整数后面紧跟的是*运算的话,我们则不能将此整数运算到sum中
2. -号同上
3. 当添加*时,我们只需要将该整数累乘进mul中,而sum没有变化。
4. 何时将mul值运算进sum中呢,就是在步骤1,2时,将旧的mul提交进sum中,将新的整数保存到mul。
另一个注意事项是,在处理整数溢出,此处使用long,而不是int。 因为long在64位系统下是64bit。
在leetcode上实际执行时间为244ms。
算法二,
此算法比较直观。
当在两个数字之间,我们有4种情况:
1, 添加+,-, *共三种情况。
2. 什么也不添加。即构成一个更大的整数。
根据上面的规则,穷举所有的情况,形成一个个表达式。然后执行该表达式。
为了节约时间,可以边构造表达式,边计算。 因为表达式之间的前面相同部分很大,不必重复进行计算。
此代码比上面略长,原因在于此处使用两段时提交。先将数从num提交到mul中,然后再从mul提交到sum中。
故在表达计算结束时,还需要提交2次,才能得到最终结果。
在leetcode上实际执行时间为544ms。
0-9and a target value, return all possibilities
to add binary operators (not unary)
+,
-,
or
*between the digits so they evaluate to the target value.
Examples:
"123", 6 -> ["1+2+3", "1*2*3"] "232", 8 -> ["2*3+2", "2+3*2"] "105", 5 -> ["1*0+5","10-5"] "00", 0 -> ["0+0", "0-0", "0*0"] "3456237490", 9191 -> []
算法一,
每得到一个新的整数,对其进行+, -, *三种运算。
使用dfs递归,免去重复计算。
此处使用sum, mul两个变量记录中间结果。 sum 存储累加和, mul 存储乘积结果。
之所以用两个,是基于如下情况:
1. 当我们在一个整数前添加+号时, 此整数后面紧跟的是*运算的话,我们则不能将此整数运算到sum中
2. -号同上
3. 当添加*时,我们只需要将该整数累乘进mul中,而sum没有变化。
4. 何时将mul值运算进sum中呢,就是在步骤1,2时,将旧的mul提交进sum中,将新的整数保存到mul。
另一个注意事项是,在处理整数溢出,此处使用long,而不是int。 因为long在64位系统下是64bit。
在leetcode上实际执行时间为244ms。
class Solution { public: vector<string> addOperators(string num, int target) { if (num.empty()) return {}; vector<string> ans; addOperators(ans, num, 0, target, 0, 0, ""); return ans; } void addOperators(vector<string>& ans, string input, int index, int target, long sum, long mul, string exp) { if (input.size() == index) { if (sum+mul == target) ans.push_back(exp.substr(1)); return; } exp.push_back('#'); const int opi = exp.size()-1; long num = 0; for (int i=index; i<input.size(); i++) { if (index+1 == i && input[index] == '0') break; // exclude numbers start with 0, e.g. 0xx num = num * 10 + input[i] - '0'; exp.push_back(input[i]); exp[opi] = '+'; addOperators(ans, input, i+1, target, sum+mul, num, exp); if (!index) continue; exp[opi] = '-'; addOperators(ans, input, i+1, target, sum+mul, -num, exp); exp[opi] = '*'; addOperators(ans, input, i+1, target, sum, mul*num, exp); } } };
算法二,
此算法比较直观。
当在两个数字之间,我们有4种情况:
1, 添加+,-, *共三种情况。
2. 什么也不添加。即构成一个更大的整数。
根据上面的规则,穷举所有的情况,形成一个个表达式。然后执行该表达式。
为了节约时间,可以边构造表达式,边计算。 因为表达式之间的前面相同部分很大,不必重复进行计算。
此代码比上面略长,原因在于此处使用两段时提交。先将数从num提交到mul中,然后再从mul提交到sum中。
故在表达计算结束时,还需要提交2次,才能得到最终结果。
在leetcode上实际执行时间为544ms。
class Solution { public: vector<string> addOperators(string num, int target) { if (num.empty()) return {}; vector<string> ans; addOperators(ans, num, 0, target, 0, 0, 0, '+', num[0], ""); return ans; } void addOperators(vector<string>& ans, string input, int index, int target, long sum, long mul, long num, char op, char ch, string exp) { if (isdigit(ch) && (exp.size()>=2 && exp.back() == '0' && !isdigit(exp[exp.size()-2]) || exp.size()==1 && exp.back() == '0')) return; // exclude integer like 0xx, +0xx, -0xx, etc. exp.push_back(ch); if (isdigit(ch)) { num = num * 10 + ch - '0'; ++index; if (index == input.size()) { if (op == '+' || op == '-') { sum += mul; mul = (44 - op) * num; // + is 43, - is 45, in ascii } else mul *= num; sum += mul; if (sum == target) ans.push_back(exp); } else { addOperators(ans, input, index, target, sum, mul, num, op, '+', exp); addOperators(ans, input, index, target, sum, mul, num, op, '-', exp); addOperators(ans, input, index, target, sum, mul, num, op, '*', exp); addOperators(ans, input, index, target, sum, mul, num, op, input[index], exp); } } else { if (op == '+' || op == '-') { sum += mul; mul = (44 - op) * num; // + is 43, - is 45, in ascii } else mul *= num; addOperators(ans, input, index, target, sum, mul, 0, ch, input[index], exp); } } };
相关文章推荐
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- C#中的尾递归与Continuation详解
- C#递归实现显示文件夹及所有文件并计算其大小的方法
- php递归创建目录的方法
- Javascript递归打印Document层次关系实例分析
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- Perl脚本实现递归遍历目录下的文件
- JavaScript的递归之递归与循环示例介绍
- C# 递归查找树状目录实现方法
- 全排列算法的非递归实现与递归实现的方法(C++)
- php递归列出所有文件和目录的代码
- java递归菜单树转换成pojo对象
- 一个JavaScript递归实现反转数组字符串的实例
- Java中的递归详解(用递归实现99乘法表来讲解)
- C语言的递归思想实例分析
- php通过递归方式复制目录和子目录的方法
- php递归法读取目录及文件的方法