Input: nums is [1, 1, 1, 1, 1], S is 3.
Output: 5
Explanation:
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
The length of the given array is positive and will not exceed 20.
The sum of elements in the given array will not exceed 1000.
Your output answer is guaranteed to be fitted in a 32-bit integer.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/target-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
果然还是自己修炼不到位,思维不够灵活!!!!
思路1:
1、用dfs来解,中间运用剪枝
2、当i用完所有数字并且目标达到,就让结果ans++;
3、sum[i]保存当前位置上,都减去或者都加上的值,进行剪枝判断:如果当前的和减去该值还比目标大,剪枝,如果当前和加上该值还是比目标小,剪枝。
class Solution {
public:
int ans = 0;
int sum[25];
void dfs(vector<int> & nums, int i, int s, int target){
if(i == nums.size() && s == target){
ans++;
}
if(s-sum[i] > target || s + sum[i] < target || i >= nums.size()) return;
else{
dfs(nums, i+1, s+nums[i], target);
dfs(nums, i+1, s-nums[i], target);
}
}
int findTargetSumWays(vector<int>& nums, int S) {
sum[nums.size()-1] = nums[nums.size()-1];
for(int i = nums.size()-2; i >= 0; i--){
sum[i] = sum[i+1] + nums[i];
}
dfs(nums, 0, 0, S);
return ans;
}
};
思路2:
1、动态规划里的01背包
2、背包是选这个包还是不选,映射为选+号还是选-号,减号不好表示,所以我们将总数往右移。
举个例子【1,1,1,1,1】 表示为-5到5
那我们就直接映射到0到10 变成【2,2,2,2,2】
所以背包容量为10,1表示一个背包的容量为2
选了一个背包 10 - 2 = 8 就还剩下8容量的背包
从0开始,值为0的方案数为1,即一个背包都不选【0,0,0,0,0】这种方案
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int s) {
int sum = accumulate(nums.begin(),nums.end(),0);
int a = sum*2+1;
if(s>=a||s+sum>=a) return 0;
vector<int> dp(a);
dp[0] = 1;
for(auto& i:nums) i=2*i;
for(int i=0;i<nums.size();i++){
for(int j=a-1;j>=nums[i];j--){ //一维背包,容量为a-1
dp[j] += dp[j-nums[i]];
}
}
return dp[sum+s];
}
};
作者:xeibinlin
链接:https://leetcode-cn.com/problems/two-sum/solution/01bei-bao-by-xeibinlin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。