
对于这题,我们可以用回溯解决,枚举所有的 + - 组合,求出答案等于target的组合个数。也可以利用动态规划来解决,且更高效。
对于 nums ,我们可以依据每个元素前面的符号来将其分为两个集合P Q,其中P为前面加正号的数,Q为前面加负号的数。
故sum(P)−sum(Q)=targetsum(P) - sum(Q) = targetsum(P)−sum(Q)=target。
又因为sum(P)+sum(Q)=sum(nums)sum(P) + sum(Q) = sum(nums)sum(P)+sum(Q)=sum(nums)
则2×sum(P)=target+sum(nums)2\times sum(P) = target + sum(nums)2×sum(P)=target+sum(nums)
其结构与 416. 分割等和子集 一模一样。
c++
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum = target + accumulate(nums.begin(), nums.end(), 0);
if(sum%2 || sum<0) return 0;
sum /= 2;
vector<int> dp(sum + 1, 0);
dp[0] = 1;
for(auto x : nums){
for(int i = sum;i >= x;i--){
dp[i] = dp[i] + dp[i-x];
}
}
return dp[sum];
}
};