From 5823b1450bf6b09465e0e52ef4832f44a7a6c700 Mon Sep 17 00:00:00 2001 From: xiaokexiang Date: Fri, 14 Jan 2022 10:47:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E5=8E=8B=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/algorithm/question/Question3.java | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/spring-boot-dependencies/spring-common/src/main/java/io/spring/common/algorithm/question/Question3.java b/spring-boot-dependencies/spring-common/src/main/java/io/spring/common/algorithm/question/Question3.java index a86f5cd..5fde3d2 100644 --- a/spring-boot-dependencies/spring-common/src/main/java/io/spring/common/algorithm/question/Question3.java +++ b/spring-boot-dependencies/spring-common/src/main/java/io/spring/common/algorithm/question/Question3.java @@ -64,28 +64,52 @@ private static int run3(int[] arr, int target) { sum += arr[i]; } // target>sum必定不存在方法数 & target和sum奇偶不同 - if (Math.abs(target) > sum || target % 2 != sum % 2) { + if (Math.abs(target) > sum || (target + sum) >> 1 == 0) { return 0; } // 动态规划,[-sum,+sum] -> [0, sum] return subset(arr, (target + sum) >> 1); } + /** + * 基于空间优化的动态规划 + */ private static int subset(int[] arr, int target) { int[] dp = new int[target + 1]; - // 不填数字也是一种解法 dp[0] = 1; - for (int k : arr) { - for (int j = target; j >= k; j--) { - dp[j] += dp[j - k]; + for (int num : arr) { + for (int j = target; j >= num; j--) { + // 如果target < num 那么肯定不会选取当前的num,也就是不会加上 dp[j - num] + dp[j] += dp[j - num]; } } return dp[target]; } + /** + * 没有空间压缩的动态规划 + */ + private static int subset2(int[] arr, int target) { + // 填充i=0和j=0的情况 + int[][] dp = new int[arr.length + 1][target + 1]; + // 第一行第一列特殊处理 + dp[0][0] = 1; + for (int i = 1; i <= arr.length; i++) { + for (int j = 0; j <= target; j++) { + // 当arr[i] > j时,没有无论加减都不会满足target,直接选择上一个 + dp[i][j] = dp[i - 1][j]; + if (j >= arr[i - 1]) { + // 当arr[i] < j时,可以选择arr[i]或者不选择arr[i],因为上面已经不选择了,现在再加上选择的 + dp[i][j] += dp[i - 1][j - arr[i - 1]]; + } + } + } + return dp[arr.length][target]; + } + public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; int target = 3; System.out.println(run3(arr, target)); } -} +} \ No newline at end of file