动态规划解题:
1.把数组中的全部值分成加法堆和减法堆, 加法堆- 减法堆 = target。加法堆+减法堆=sum。递推公式为加法堆等于(sum+targe)/2;
2.定义的dp数组表示的是0到i个物品中凑齐背包容量的不同中方法。
3.初始化二维数组的第0列和第0行后,来进行dp数组的递推。
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum=0;
int len=nums.length;
for(int i:nums){
sum+=i;
}
//防止特殊的情况,例如背包容量不能分成正数,背包容量为负数时直接返回0
if (sum<0 ||(sum+target)%2!=0 || (sum+target)<0){
return 0;
}
//定义一个二维数组表示0到i个物品中凑齐背包容量的不同方法有多少种
int [][] dp=new int [len][((sum+target)/2)+1];
//初始化第o行的值
for(int j=0;j<=(sum+target)/2;j++){
if(nums[0]==j){
dp[0][j]=1;
}
}
//初始化第0列的值,因为数组中的值可能有0在,所以也能装入背包中
int numZeros = 0;
for(int i = 0; i < len; i++) {
if(nums[i] == 0) {
numZeros++;
}
dp[i][0] = (int) Math.pow(2, numZeros);
}
//遍历dp数组,来进行递推,dp数组的推导公式为放物品i和不放物品i,两种装入背包方法
for (int i=1;i<len;i++){
for (int j=0;j<=(sum+target)/2;j++){
if (j>=nums[i]){
dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];
}else{
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[len-1][(sum+target)/2];
}
}