leecode更新
This commit is contained in:
parent
09b670943b
commit
ed9b70527a
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.markilue.leecode.dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: Leecode
|
||||||
|
* @BelongsPackage: com.markilue.leecode.dynamic
|
||||||
|
* @Author: markilue
|
||||||
|
* @CreateTime: 2022-11-25 19:51
|
||||||
|
* @Description:
|
||||||
|
* TODO 力扣494题 难度中等:
|
||||||
|
* 给你一个整数数组 nums 和一个整数 target 。
|
||||||
|
* 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
|
||||||
|
* 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
|
||||||
|
* 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T10_FindTargetSumWays {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码随想录尝试动态规划法:本题要如何使表达式结果为target。既然为target,那么就一定有 left组合 - right组合 = target。所以还是可以转为背包问题
|
||||||
|
* left + right等于sum,而sum是固定的。公式来了, left - (sum - left) = target -> left = (target + sum)/2 。此时问题就是在集合nums中找出和为left的组合。
|
||||||
|
* TODO 也就是说可以转为填满背包大小为left有几种方法。这与之前的背包问题不同。之前都是求容量为j的背包最多能装多少,
|
||||||
|
* TODO 动态规划五部曲:
|
||||||
|
* 1)dp数组的定义: dp[i][j] 满j(包括j)这么大容积的包,有dp[j]种方法: 使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。
|
||||||
|
* 2)dp数组的状态转移方程:
|
||||||
|
* 例如:dp[j],j 为5,
|
||||||
|
* 已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 dp[5]。
|
||||||
|
* 已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 dp[5]。
|
||||||
|
* 已经有一个3(nums[i]) 的话,有 dp[2]中方法 凑成 dp[5]
|
||||||
|
* 已经有一个4(nums[i]) 的话,有 dp[1]中方法 凑成 dp[5]
|
||||||
|
* 已经有一个5 (nums[i])的话,有 dp[0]中方法 凑成 dp[5]
|
||||||
|
* 所以求组合类问题的公式,都是类似这种:
|
||||||
|
* dp[j] += dp[j - nums[i]]
|
||||||
|
* 3)dp数组初始化: dp[i][0]=0
|
||||||
|
* 4)dp数组的遍历顺序:
|
||||||
|
* 5)dp的举例推导:当nums=[1,1,1,1,1],target=3时
|
||||||
|
* [0 1 2 3 4]
|
||||||
|
* i=0 0 1 1 1 1
|
||||||
|
* i=1 0 1 2 2 2
|
||||||
|
* i=2 0 1 2 3 3
|
||||||
|
* i=3 0 1 2 3 4
|
||||||
|
* i=4 0 1 2 3 4
|
||||||
|
* @param nums
|
||||||
|
* @param target
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int findTargetSumWays(int[] nums, int target) {
|
||||||
|
|
||||||
|
int sum =0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
sum+=nums[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = (sum+target)/2;
|
||||||
|
|
||||||
|
int[][] dp = new int[nums.length][left+1];
|
||||||
|
|
||||||
|
for (int i = 0; i < dp.length; i++) {
|
||||||
|
for (int j = 0; j <= left; j++) {
|
||||||
|
if(j<nums[i]) dp[i][j]=dp[i-1][j];
|
||||||
|
else dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue