算法题目 : Expression Add Operators
算法题目描述:
Given a string that contains only digits 0-9
and 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 -> []
算法分析:
这道题目主要就是问给定一串数,在数字中间插入操作符构成表达式,计算表达式,使得结果等于target。
因为要输出所有可能的情况,所以优先想到的就是用深度优先搜索。问题在于如何将问题拆分成多次搜索。加减法很好处理,每当我们截出一段数字时,将之前计算的结果加上或者减去这个数,就可以将剩余的数字字符串和新的计算结果代入下一次搜索中了,直到我们的计算结果和目标一样,就完成了一次搜索。而对于*并且之前为+或-,需要恢复上一次+或-的计算值,先计算当前的*,然后再执行之前运算的逆运算。这样下来我们计算得到的时间复杂度是O(n^2),这相比LeetCode里面的其他大神用的算法最快可达到O(n)来说,就显得很慢了,但是大神用的算法实在是看不懂,应该是用了加入了一些分治的思想。我们还是用简单易懂的DFS来实现吧。
算法代码(C++):
class Solution {
public:
vector<string> addOperators(string num, int target) {
vector<string> res;
string temp;
dfs(res, num, temp, target, 0, 0, 0);
return res;
}
void dfs(vector<string>& res, const string& nums, string temp, const int target, int start, long long pre_val, long long cur_res){
if(start==nums.size()){
if(cur_res==target){
res.push_back(temp);
}
return;
}
for(int i=1;i+start<=nums.size();++i){
string num=nums.substr(start,i);
if(num.size()>1&&num[0]=='0')
return;
long long cur=stoll(num);
if(start==0){
dfs(res, nums, num, target, i, cur, cur);
}
else{
dfs(res, nums, temp+"+"+num, target, start+i, cur, cur_res+cur);
dfs(res, nums, temp+"-"+num, target, start+i, -cur, cur_res-cur);
dfs(res, nums, temp+"*"+num, target, start+i, pre_val*cur, cur_res-pre_val+pre_val*cur);
}
}
}
};
class Solution {
public:
vector<string> addOperators(string num, int target) {
vector<string> res;
string temp;
dfs(res, num, temp, target, 0, 0, 0);
return res;
}
void dfs(vector<string>& res, const string& nums, string temp, const int target, int start, long long pre_val, long long cur_res){
if(start==nums.size()){
if(cur_res==target){
res.push_back(temp);
}
return;
}
for(int i=1;i+start<=nums.size();++i){
string num=nums.substr(start,i);
if(num.size()>1&&num[0]=='0')
return;
long long cur=stoll(num);
if(start==0){
dfs(res, nums, num, target, i, cur, cur);
}
else{
dfs(res, nums, temp+"+"+num, target, start+i, cur, cur_res+cur);
dfs(res, nums, temp+"-"+num, target, start+i, -cur, cur_res-cur);
dfs(res, nums, temp+"*"+num, target, start+i, pre_val*cur, cur_res-pre_val+pre_val*cur);
}
}
}
};