mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-05 22:59:31 +08:00
Merge pull request #2877 from asnsuyu/master
docs: 为 0494.目标和.md 完善了 JavaDoc 注释, 添加了动规五部曲注释, 规范了部分代码格式, 修改了部分变量名以增强代码语义化
This commit is contained in:
@ -825,30 +825,69 @@ func abs(x int) int {
|
||||
|
||||
### JavaScript
|
||||
```javascript
|
||||
/**
|
||||
* 题目来源: {@link https://leetcode.cn/problems/target-sum/}
|
||||
*
|
||||
* 题解来源: {@link https://programmercarl.com/0494.%E7%9B%AE%E6%A0%87%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE}
|
||||
*
|
||||
* 时间复杂度: O(n * C), C 为数组元素总和与目标值之和的一半
|
||||
*
|
||||
* 空间复杂度: O(C)
|
||||
*
|
||||
* @param { number[] } nums
|
||||
* @param { number } target
|
||||
* @return { number }
|
||||
*/
|
||||
const findTargetSumWays = (nums, target) => {
|
||||
// 原题目可转化为:
|
||||
//
|
||||
// 将所有元素划分为 2 个集合,
|
||||
// 一个集合中包含所有要添加 "+" 号的元素, 一个集合中包含所有要添加 "-" 号的元素
|
||||
//
|
||||
// 设两个集合的元素和分别为 positive 和 negative, 所有元素总和为 sum, 那么有如下等式:
|
||||
// positive + negative = sum (1)
|
||||
// positive - negative = target (2)
|
||||
// (1) 与 (2) 联立可得: positive = (sum + target) / 2,
|
||||
// 所以如果能从原数组中取出若干个元素形成 1 个元素总和为 (sum + target) / 2 的集合,
|
||||
// 就算得到了 1 种满足题意的组合方法
|
||||
//
|
||||
// 因此, 所求变为: 有多少种取法, 可使得容量为 (sum + target) / 2 的背包被装满?
|
||||
|
||||
const sum = nums.reduce((a, b) => a+b);
|
||||
const sum = nums.reduce((a, b) => a + b);
|
||||
|
||||
if(Math.abs(target) > sum) {
|
||||
if (Math.abs(target) > sum) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((target + sum) % 2) {
|
||||
if ((target + sum) % 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const halfSum = (target + sum) / 2;
|
||||
|
||||
let dp = new Array(halfSum+1).fill(0);
|
||||
const bagWeight = (target + sum) / 2;
|
||||
|
||||
// 1. dp 数组的含义
|
||||
// dp[j]: 装满容量为 j 的背包, 有 dp[j] 种方法
|
||||
let dp = new Array(bagWeight + 1).fill(0);
|
||||
|
||||
// 2. 递推公式
|
||||
// dp[j] = Σ(dp[j - nums[j]]), (j ∈ [0, j] 且 j >= nums[j])
|
||||
// 因为 dp[j - nums[j]] 表示: 装满容量为 j - nums[j] 背包有 dp[j - nums[j]] 种方法
|
||||
// 而容量为 j - nums[j] 的背包只需要再将 nums[j] 放入背包就能使得背包容量达到 j
|
||||
// 因此, 让背包容量达到 j 有 Σ(dp[j - nums[j]]) 种方法
|
||||
|
||||
// 3. dp 数组如何初始化
|
||||
// dp[0] = 1, dp[1 ~ bagWeight] = 0
|
||||
dp[0] = 1;
|
||||
|
||||
for(let i = 0; i < nums.length; i++) {
|
||||
for(let j = halfSum; j >= nums[i]; j--) {
|
||||
|
||||
// 4. 遍历顺序
|
||||
// 先物品后背包, 物品从前往后遍历, 背包容量从后往前遍历
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
for (let j = bagWeight; j >= nums[i]; j--) {
|
||||
dp[j] += dp[j - nums[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return dp[halfSum];
|
||||
return dp[bagWeight];
|
||||
};
|
||||
```
|
||||
|
||||
|
Reference in New Issue
Block a user