7.28 动态规划二刷

This commit is contained in:
zhangsan 2025-07-28 21:21:05 +08:00
parent b13a106fec
commit 823fb099f9
3 changed files with 35 additions and 11 deletions

View File

@ -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];

View File

@ -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];
}
}

View File

@ -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) {