4 动态规划解目标和

来源:LeetCode第494题

难度:中等

描述:给你一个整数数组nums和一个整数target,向数组中每个整数前添加'+'或'-'然后串联起来所有整数,可以构造一个表达式:例如,nums=[2,1]可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式的数据;

递归方式求解:

//定义一个递归函数,传参时数组、目标和、下标
public int getTarget(int []nums,int target,int index)
{
//如果index超过了nums.length,表示已经把所有的内容遍历完毕了
if(index>=nums.length)
{
//遍历完毕的情况下,如果target==0,则表示这条路走得通,返回1
if(targert==0)
{
return 1;
}else
{
//在遍历完毕的情况下,如果target!=0,表示这条路走不通,返回0
return 0;
}
}
//每一个数字都可以进行+或-,从而两条路进行寻找
return getTarget(nums,target+nums[index],index+1)+getTarget(nums,target-nums[index],index+1);

}

求解思路:我们假设在一些数字前添加'+',这些数字的和式plusSum,剩下的数字前添加'-',这些数字的和式minusSum.我们的要求是plusSum-minusSum=target(公式1)的方案数目,我们假设所有元素的和是sum,那么哦们可以得到plusSum+minusSum=sum(公式2);由公式1和公式2我们可以得到minusSum*2=sum-target;.我们可以看到如果要想上面等式成立,sum-target一定是偶数,且只需要找出一些数字让他们的和等于minusSum,也就是(sum-target)/2的方案数。
递归方式求解:

public int getTarget2(int []nums,int target,int index)
{
if(index>=nums.length)
{
if(target==0)
{
return 1;
}else
{
return 0;
}
}
return getTarget2(nums,target,index+1)+getTarget2(nums,target-nums[index],index+1);
}

除此之外还可以看做是背包问题dp[i][j]表示前i个字符中能组成和为j的数目对于一个数字可以有选和不选两种选择,从而dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];
 

public int getTarget3(int []nums,int target)
{
int dp[][]=new int[nums.length][target];
if(nums[0]==0)
{
dp[0][0]=1;
}else{
dp[0][0]=0;
}
for(int i=1;i=nums[i])
{
dp[i][j]=dp[i-1][j]+dp[i-1][j-num[i]]
}else
{
dp[i][j]=dp[i-1][j];
}
}
}
}

你可能感兴趣的:(JAVA刷题500道,动态规划,算法,数据结构,java)