Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e5b75df

Browse files
Merge pull request youngyangyang04#2877 from asnsuyu/master
docs: 为 0494.目标和.md 完善了 JavaDoc 注释, 添加了动规五部曲注释, 规范了部分代码格式, 修改了部分变量名以增强代码语义化
2 parents bba027e + bb12666 commit e5b75df

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

‎problems/0494.目标和.md

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -825,30 +825,69 @@ func abs(x int) int {
825825

826826
### JavaScript
827827
```javascript
828+
/**
829+
* 题目来源: {@link https://leetcode.cn/problems/target-sum/}
830+
*
831+
* 题解来源: {@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}
832+
*
833+
* 时间复杂度: O(n * C), C 为数组元素总和与目标值之和的一半
834+
*
835+
* 空间复杂度: O(C)
836+
*
837+
* @param { number[] } nums
838+
* @param { number } target
839+
* @return { number }
840+
*/
828841
const findTargetSumWays = (nums, target) => {
829-
830-
const sum = nums.reduce((a, b) => a+b);
842+
// 原题目可转化为:
843+
//
844+
// 将所有元素划分为 2 个集合,
845+
// 一个集合中包含所有要添加 "+" 号的元素, 一个集合中包含所有要添加 "-" 号的元素
846+
//
847+
// 设两个集合的元素和分别为 positive 和 negative, 所有元素总和为 sum, 那么有如下等式:
848+
// positive + negative = sum (1)
849+
// positive - negative = target (2)
850+
// (1) 与 (2) 联立可得: positive = (sum + target) / 2,
851+
// 所以如果能从原数组中取出若干个元素形成 1 个元素总和为 (sum + target) / 2 的集合,
852+
// 就算得到了 1 种满足题意的组合方法
853+
//
854+
// 因此, 所求变为: 有多少种取法, 可使得容量为 (sum + target) / 2 的背包被装满?
855+
856+
const sum = nums.reduce((a, b) => a + b);
831857

832-
if(Math.abs(target) > sum) {
858+
if(Math.abs(target) > sum) {
833859
return 0;
834860
}
835861

836-
if((target + sum) % 2) {
862+
if((target + sum) % 2) {
837863
return 0;
838864
}
839865

840-
const halfSum = (target + sum) / 2;
841-
842-
let dp = new Array(halfSum+1).fill(0);
866+
const bagWeight = (target + sum) / 2;
867+
868+
// 1. dp 数组的含义
869+
// dp[j]: 装满容量为 j 的背包, 有 dp[j] 种方法
870+
let dp = new Array(bagWeight + 1).fill(0);
871+
872+
// 2. 递推公式
873+
// dp[j] = Σ(dp[j - nums[j]]), (j ∈ [0, j] 且 j >= nums[j])
874+
// 因为 dp[j - nums[j]] 表示: 装满容量为 j - nums[j] 背包有 dp[j - nums[j]] 种方法
875+
// 而容量为 j - nums[j] 的背包只需要再将 nums[j] 放入背包就能使得背包容量达到 j
876+
// 因此, 让背包容量达到 j 有 Σ(dp[j - nums[j]]) 种方法
877+
878+
// 3. dp 数组如何初始化
879+
// dp[0] = 1, dp[1 ~ bagWeight] = 0
843880
dp[0] = 1;
844-
845-
for(let i = 0; i < nums.length; i++) {
846-
for(let j = halfSum; j >= nums[i]; j--) {
881+
882+
// 4. 遍历顺序
883+
// 先物品后背包, 物品从前往后遍历, 背包容量从后往前遍历
884+
for (let i = 0; i < nums.length; i++) {
885+
for (let j = bagWeight; j >= nums[i]; j--) {
847886
dp[j] += dp[j - nums[i]];
848887
}
849888
}
850889

851-
return dp[halfSum];
890+
return dp[bagWeight];
852891
};
853892
```
854893

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /