diff --git "a/problems/0494.\347\233\256\346\240\207\345\222\214.md" "b/problems/0494.\347\233\256\346\240\207\345\222\214.md" index b161bc57a8..4377540403 100755 --- "a/problems/0494.\347\233\256\346\240\207\345\222\214.md" +++ "b/problems/0494.\347\233\256\346\240\207\345\222\214.md" @@ -40,7 +40,7 @@ **[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[装满背包有多少种方法?| LeetCode:494.目标和](https://www.bilibili.com/video/BV1o8411j73x/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 -## 思路 +## 思路1 如果对背包问题不都熟悉先看这两篇: @@ -65,6 +65,13 @@ target是固定的,sum是固定的,left就可以求出来。 此时问题就是在集合nums中找出和为left的组合。 +## 思路2 +实现nums运用+、-组合为target,设计sum表示nums所有元素之和,那么会有diff = sum - targe, 这个diff即为nums中取了“-”的数字之和的2倍: + +举例:sum = a+b, target = a-b, 则有sum - target = (a+b)-(a-b)=2b, b = (sum-target)/2, 这里b就可以理解为所有被减数之和。 + +所以这里就有:diff = sum - target, 如果diff < 0 || diff % 2 == 1, 就无法组合出来target,返回为0;neg = diff/2表示所有被减数之和,我们只需要求出组合出neg的方法即可。 + ### 回溯算法 在回溯算法系列中,一起学过这道题目[回溯算法:39. 组合总和](https://programmercarl.com/0039.组合总和.html)的录友应该感觉很熟悉,这不就是组合总和问题么? @@ -821,6 +828,34 @@ func abs(x int) int { } ``` +一维dp +```go +func findTargetSumWays(nums []int, target int) int { + sum := 0 + for _, v := range nums { + sum += v + } + diff := sum - target + if diff < 0 || diff%2 == 1 { + return 0 + } + neg := diff/2 + // 定义dp数组 + dp := make([]int, neg+1) + // 初始化 + dp[0] = 1 + // 遍历顺序 + for i := 0; i < len(nums); i++ { + for j := neg; j >= nums[i]; j-- { + //推导公式 + dp[j] += dp[j-nums[i]] + //fmt.Println(dp) + } + } + return dp[neg] +} +``` + ### JavaScript ```javascript /**