diff --git a/Leecode/src/main/java/com/markilue/leecode/dynamic/T13_CombinationSum4.java b/Leecode/src/main/java/com/markilue/leecode/dynamic/T13_CombinationSum4.java index 9954306..e2070e1 100644 --- a/Leecode/src/main/java/com/markilue/leecode/dynamic/T13_CombinationSum4.java +++ b/Leecode/src/main/java/com/markilue/leecode/dynamic/T13_CombinationSum4.java @@ -2,6 +2,8 @@ package com.markilue.leecode.dynamic; import org.junit.Test; +import java.util.Arrays; + /** * @BelongsProject: Leecode * @BelongsPackage: com.markilue.leecode.dynamic @@ -38,6 +40,7 @@ public class T13_CombinationSum4 { * (3)dp初始化:dp[i][0]=1且dp[0][j%num[0]==0]=1 * (4)dp遍历顺序:由于是排列问题,因此先背包后num[i] * (5)dp举例推导: + * 速度击败97.72% 内存击败90.4% * @param nums * @param target * @return @@ -58,4 +61,33 @@ public class T13_CombinationSum4 { return dp[target]; } + + + /** + * 官方最快:记忆化搜索:回溯+记忆化搜索 + * 速度击败100% 内存击败96% + * @param nums + * @param target + * @return + */ + public int combinationSum41(int[] nums, int target) { + int[] memo = new int[target + 1]; + Arrays.fill(memo, -1); + memo[0] = 1; + return search(memo, nums, target); + } + + public int search(int[] memo, int[] nums, int target){ + if(memo[target] != -1){ + return memo[target]; + } + int res = 0; + for(int i : nums){ + if(target >= i){ + res += search(memo, nums, target - i); + } + } + memo[target] = res;//全部遍历完就填充记忆;避免下一次继续计算 + return res; + } } diff --git a/Leecode/src/main/java/com/markilue/leecode/dynamic/second/T13_CombinationSum4.java b/Leecode/src/main/java/com/markilue/leecode/dynamic/second/T13_CombinationSum4.java new file mode 100644 index 0000000..180a372 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/dynamic/second/T13_CombinationSum4.java @@ -0,0 +1,53 @@ +package com.markilue.leecode.dynamic.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.dynamic.second + *@Author: dingjiawen + *@CreateTime: 2023-02-18 19:06 + *@Description: + * TODO 力扣377题 组合总和Iv: + * 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 + * 题目数据保证答案符合 32 位整数范围。 + *@Version: 1.0 + */ +public class T13_CombinationSum4 { + + @Test + public void test() { + int[] nums = {1, 2, 3}; + int target = 4; + System.out.println(combinationSum4(nums, target)); + } + + + /** + * 思路:还是完全背包问题:数字可以无限使用,但是不同的是:顺序不同算不同的组合,所以nums遍历需要放里面 + * TODO DP五部曲: + * 1.dp定义: dp[i][j]表示使用nums[0-i]可能凑出j的个数 + * 2.dp状态转移方程: dp[i][j] 可以使用当前的数 或者 不使用当前的数 + * dp[i][j]=dp[i][j-nums[i]]+dp[i-1][j] + * 3.dp初始化: dp[0][j%nums[0]]=1 + * 4.dp遍历顺序: 由于顺序不同算不同的组合:所以先从上到下;再从前往后 + * 5.dp举例推导: + * @param nums + * @param target + * @return + */ + public int combinationSum4(int[] nums, int target) { + + int[] dp = new int[target + 1]; + dp[0] = 1; + + for (int j = 0; j < dp.length; j++) { + for (int i = 0; i < nums.length; i++) { + if (j >= nums[i]) dp[j] += dp[j - nums[i]]; + } + } + return dp[target]; + + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java index 5174daa..68c0046 100644 --- a/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java +++ b/Leecode/src/main/java/com/markilue/leecode/greedy/second/T02_WiggleMaxLength.java @@ -79,7 +79,7 @@ public class T02_WiggleMaxLength { int curdiff = 0; //记录现在的差值 int prediff = 0; //记录上次的差值 for (int i = 0; i < nums.length - 1; i++) { - curdiff = nums[i + 1] - nums[i]; + curdiff = nums[i + 1] - nums[i] ; if ((prediff >= 0 && curdiff < 0) || (prediff <= 0 && curdiff > 0)) { result++; prediff = curdiff;