|
|
@@ -0,0 +1,59 @@
|
|
|
+package leetcode.p494;
|
|
|
+
|
|
|
+import java.util.Arrays;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ProjectName: LeetCode
|
|
|
+ * @FileName: Solution
|
|
|
+ * @Author: 杨逸
|
|
|
+ * @Data:2025/8/12 13:59
|
|
|
+ * @Description: https://leetcode.cn/problems/target-sum/description/
|
|
|
+ * 494. 目标和
|
|
|
+ */
|
|
|
+class Solution {
|
|
|
+ int[] n;
|
|
|
+ int[][] f;
|
|
|
+ public int findTargetSumWays(int[] nums, int target) {
|
|
|
+ /**
|
|
|
+ * 思路:动态规划(记忆化搜索)
|
|
|
+ * p:表示正数的和
|
|
|
+ * s:表示nums的和
|
|
|
+ * s-p:表示负数的和
|
|
|
+ *所以:p - (s - p) = target
|
|
|
+ * p = (target + s) / 2
|
|
|
+ * 又因为nums是整数,所以(target + s) / 2必须是正整数
|
|
|
+ * 问题转化为从nums中选出一些数,使其和为(target + s) / 2的方案数
|
|
|
+ */
|
|
|
+ n = nums;
|
|
|
+ target += Arrays.stream(nums).sum();
|
|
|
+ if (target % 2 != 0 || target < 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ target /= 2;
|
|
|
+ f = new int[nums.length][target+1];
|
|
|
+ for (int i = 0; i < f.length; i++) {
|
|
|
+ Arrays.fill(f[i],-1);
|
|
|
+ }
|
|
|
+ return dfs(nums.length-1,target);
|
|
|
+ }
|
|
|
+
|
|
|
+ private int dfs(int i, int target) {
|
|
|
+ //边界条件
|
|
|
+ if(i<0){
|
|
|
+ //选出的数刚好等于p,合法方案数+1
|
|
|
+ return target == 0 ? 1 : 0;
|
|
|
+ }
|
|
|
+ //之前计算过
|
|
|
+ if(f[i][target] != -1){
|
|
|
+ return f[i][target];
|
|
|
+ }
|
|
|
+ //不选的方案数计算
|
|
|
+ int res = dfs(i-1,target);
|
|
|
+ //能选方案数
|
|
|
+ if(target >= n[i]){
|
|
|
+ res += dfs(i-1,target-n[i]);
|
|
|
+ }
|
|
|
+ //记忆化
|
|
|
+ return f[i][target] = res;
|
|
|
+ }
|
|
|
+}
|