diff --git a/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java b/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java new file mode 100644 index 0000000..0d2e6ac --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/dynamic/T10_FindTargetSumWays.java @@ -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