问题描述
简要思路
刚开始用暴力,显然超时了。
然后 使用 dfs 或者说是回溯优化,对每一个节点有 + 和 - 两个分支,在最终的叶子节点寻找 target。
代码
解法1(暴力):
class Solution {
public:
int mi(int x){
int res = 2;
for(int i = 1; i < x; i++){
res *= 2;
}
return res;
}
int findTargetSumWays(vector<int>& nums, int target) {
int n = nums.size();
int m = mi(n + 1);
vector<int> tree(m, 0);
int ans = 0;
for(int i = 0, j = 2; i < n; i++){
int leaf = mi(i + 2);
if(i == n - 1){
while(j < leaf){
tree[j] = tree[j / 2] + nums[i];
if(tree[j] == target) ans++;
j++;
tree[j] = tree[j / 2] - nums[i];
if(tree[j] == target) ans++;
j++;
}
}
while(j < leaf){
tree[j] = tree[j / 2] + nums[i];
j++;
tree[j] = tree[j / 2] - nums[i];
j++;
}
}
return ans;
}
};
解法2(dfs):
class Solution {
public:
int ans = 0;
void dfs(vector<int>& nums, int deep, int sum, int target){
if(deep == nums.size()) return;
int sum1 = sum + nums[deep];
int sum2 = sum - nums[deep];
if(deep == nums.size() - 1){
if(sum1 == target) ans++;
if(sum2 == target) ans++;
}
dfs(nums, deep + 1, sum1, target);
dfs(nums, deep + 1, sum2, target);
}
int findTargetSumWays(vector<int>& nums, int target){
int n = nums.size();
dfs(nums, 0, 0, target);
return ans;
}
};