diff --git a/src/main/java/dynamic_programming/CombinationSum4.java b/src/main/java/dynamic_programming/CombinationSum4.java index 5c8a100..042b8af 100644 --- a/src/main/java/dynamic_programming/CombinationSum4.java +++ b/src/main/java/dynamic_programming/CombinationSum4.java @@ -20,6 +20,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/combination-sum-iv/ */ +//二刷会做 public class CombinationSum4 { public int combinationSum4(int[] nums, int target) { int[]dp=new int[target+1]; diff --git a/src/main/java/dynamic_programming/FindMaxForm.java b/src/main/java/dynamic_programming/FindMaxForm.java index 1b43933..6cd1975 100644 --- a/src/main/java/dynamic_programming/FindMaxForm.java +++ b/src/main/java/dynamic_programming/FindMaxForm.java @@ -13,26 +13,40 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/ones-and-zeroes/ */ +//二刷不会 public class FindMaxForm { - int[] cnt(String str){ - int cntzero=0,cntone=0; + // 统计字符串中 '0' 和 '1' 的数量 + private int[] countZeroAndOne(String str) { + int cntZero = 0, cntOne = 0; for (int i = 0; i < str.length(); i++) { - if(str.charAt(i)=='0') - cntzero++; - else cntone++; + if (str.charAt(i) == '0') { + cntZero++; + } else { + cntOne++; + } } - return new int[]{cntzero,cntone}; + return new int[]{cntZero, cntOne}; } + public int findMaxForm(String[] strs, int m, int n) { - int[][]dp=new int[m+1][n+1]; //最多m个0 n个1,能选取的字符串的个数 而不是组合数! + // dp[j][k] 表示最多使用 j 个 '0' 和 k 个 '1' 时能选取的最大子集长度 + int[][] dp = new int[m + 1][n + 1]; + + // 遍历每个字符串 for (String str : strs) { - int[] res = cnt(str); - for (int j = m; j >= res[0]; j--) { - for (int k = n; k >= res[1]; k--) { - dp[j][k] =Math.max(dp[j][k],dp[j - res[0]][k - res[1]]+1); + int[] cnt = countZeroAndOne(str); + int cntZero = cnt[0], cntOne = cnt[1]; + + // 逆序遍历 j 和 k,避免重复计算 + for (int j = m; j >= cntZero; j--) { + for (int k = n; k >= cntOne; k--) { + // 选择当前字符串:dp[j - cntZero][k - cntOne] + 1 + // 不选择当前字符串:dp[j][k] + dp[j][k] = Math.max(dp[j][k], dp[j - cntZero][k - cntOne] + 1); } } } + return dp[m][n]; } } diff --git a/src/main/java/dynamic_programming/FindTargetSumWays.java b/src/main/java/dynamic_programming/FindTargetSumWays.java index c351346..8ca7426 100644 --- a/src/main/java/dynamic_programming/FindTargetSumWays.java +++ b/src/main/java/dynamic_programming/FindTargetSumWays.java @@ -18,7 +18,16 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/target-sum/ */ +//二刷不会 public class FindTargetSumWays { + + /** + * 为了找到所有可能的表达式数目,可以将问题转化为一个子集和问题。具体来说: + * 将添加 + 的数字归为一部分,称为正集合 P。 + * 将添加 - 的数字归为另一部分,称为负集合 N。 + 那么有 P - N = target + * @return + */ public int findTargetSumWays(int[] nums, int target) { int sum = 0; for (int num : nums) {