leecode更新

This commit is contained in:
markilue 2022-11-25 22:03:31 +08:00
parent 09b670943b
commit ed9b70527a
1 changed files with 67 additions and 0 deletions

View File

@ -0,0 +1,67 @@
package com.markilue.leecode.dynamic;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.dynamic
* @Author: markilue
* @CreateTime: 2022-11-25 19:51
* @Description:
* TODO 力扣494题 难度中等
* 给你一个整数数组 nums 和一个整数 target
* 向数组中的每个整数前添加 '+' '-' 然后串联起所有整数可以构造一个 表达式
* 例如nums = [2, 1] 可以在 2 之前添加 '+' 1 之前添加 '-' 然后串联起来得到表达式 "+2-1"
* 返回可以通过上述方法构造的运算结果等于 target 的不同 表达式 的数目
* @Version: 1.0
*/
public class T10_FindTargetSumWays {
/**
* 代码随想录尝试动态规划法:本题要如何使表达式结果为target既然为target那么就一定有 left组合 - right组合 = target所以还是可以转为背包问题
* left + right等于sum而sum是固定的公式来了 left - (sum - left) = target -> left = (target + sum)/2 此时问题就是在集合nums中找出和为left的组合
* TODO 也就是说可以转为填满背包大小为left有几种方法这与之前的背包问题不同之前都是求容量为j的背包最多能装多少
* TODO 动态规划五部曲:
* 1)dp数组的定义: dp[i][j] 满j包括j这么大容积的包有dp[j]种方法 使用 下标为[0, i]的nums[i]能够凑满j包括j这么大容量的包有dp[i][j]种方法
* 2)dp数组的状态转移方程:
* 例如dp[j]j 为5
* 已经有一个1nums[i] 的话 dp[4]种方法 凑成 dp[5]
* 已经有一个2nums[i] 的话 dp[3]种方法 凑成 dp[5]
* 已经有一个3nums[i] 的话 dp[2]中方法 凑成 dp[5]
* 已经有一个4nums[i] 的话 dp[1]中方法 凑成 dp[5]
* 已经有一个5 nums[i]的话 dp[0]中方法 凑成 dp[5]
* 所以求组合类问题的公式都是类似这种
* dp[j] += dp[j - nums[i]]
* 3)dp数组初始化: dp[i][0]=0
* 4)dp数组的遍历顺序:
* 5)dp的举例推导:当nums=[1,1,1,1,1],target=3时
* [0 1 2 3 4]
* i=0 0 1 1 1 1
* i=1 0 1 2 2 2
* i=2 0 1 2 3 3
* i=3 0 1 2 3 4
* i=4 0 1 2 3 4
* @param nums
* @param target
* @return
*/
public int findTargetSumWays(int[] nums, int target) {
int sum =0;
for (int i = 0; i < nums.length; i++) {
sum+=nums[i];
}
int left = (sum+target)/2;
int[][] dp = new int[nums.length][left+1];
for (int i = 0; i < dp.length; i++) {
for (int j = 0; j <= left; j++) {
if(j<nums[i]) dp[i][j]=dp[i-1][j];
else dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
}
}
return 0;
}
}