37
37
<li>保证返回的最终结果能被 32 位整数存下。</li>
38
38
</ul >
39
39
40
-
41
40
## 解法
42
41
43
42
<!-- 这里可写通用的实现逻辑 -->
44
43
45
- 类似背包问题 ,只不过下标可能会出现负数,需要特殊处理。
44
+ 题目可以转换为 ` 0-1 ` 背包问题 ,只不过下标可能会出现负数,需要特殊处理。
46
45
47
46
<!-- tabs:start -->
48
47
@@ -65,6 +64,44 @@ class Solution:
65
64
return dp[n - 1 ][target + 1000 ]
66
65
```
67
66
67
+ 设:添加 ` - ` 号的元素之和为 ` x ` ,则添加 ` + ` 号的元素之和为 ` s - x ` ,` s - x - x = target ` ,` 2x = s - target ` 。需要满足 ` s - target ` 一定大于等于 0,并且能够被 2 整除。
68
+
69
+ ``` python
70
+ class Solution :
71
+ def findTargetSumWays (self , nums : List[int ], target : int ) -> int :
72
+ s = sum (nums)
73
+ if s - target < 0 or (s - target) % 2 != 0 :
74
+ return 0
75
+ target = (s - target) // 2 + 1
76
+ n = len (nums) + 1
77
+ dp = [[0 ] * target for _ in range (n)]
78
+ dp[0 ][0 ] = 1
79
+ for i in range (1 , n):
80
+ for j in range (target):
81
+ dp[i][j] = dp[i - 1 ][j]
82
+ if nums[i - 1 ] <= j:
83
+ dp[i][j] += dp[i - 1 ][j - nums[i - 1 ]]
84
+ return dp[- 1 ][- 1 ]
85
+ ```
86
+
87
+ 空间优化:
88
+
89
+ ``` python
90
+ class Solution :
91
+ def findTargetSumWays (self , nums : List[int ], target : int ) -> int :
92
+ s = sum (nums)
93
+ if s - target < 0 or (s - target) % 2 != 0 :
94
+ return 0
95
+ target = (s - target) // 2 + 1
96
+ n = len (nums) + 1
97
+ dp = [0 ] * target
98
+ dp[0 ] = 1
99
+ for i in range (1 , n):
100
+ for j in range (target - 1 , nums[i - 1 ] - 1 , - 1 ):
101
+ dp[j] += dp[j - nums[i - 1 ]]
102
+ return dp[- 1 ]
103
+ ```
104
+
68
105
### ** Java**
69
106
70
107
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -95,6 +132,57 @@ class Solution {
95
132
}
96
133
```
97
134
135
+ 空间优化:
136
+
137
+ ``` java
138
+ class Solution {
139
+ public int findTargetSumWays (int [] nums , int target ) {
140
+ int s = 0 ;
141
+ for (int x : nums) {
142
+ s += x;
143
+ }
144
+ if (s - target < 0 || (s - target) % 2 != 0 ) {
145
+ return 0 ;
146
+ }
147
+ target = (s - target) / 2 + 1 ;
148
+ int [] dp = new int [target];
149
+ dp[0 ] = 1 ;
150
+ for (int i = 1 ; i < nums. length + 1 ; ++ i) {
151
+ for (int j = target - 1 ; j >= nums[i - 1 ]; -- j) {
152
+ dp[j] += dp[j - nums[i - 1 ]];
153
+ }
154
+ }
155
+ return dp[target - 1 ];
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### ** C++**
161
+
162
+ 空间优化:
163
+
164
+ ``` cpp
165
+ class Solution {
166
+ public:
167
+ int findTargetSumWays(vector<int >& nums, int target) {
168
+ int s = 0;
169
+ for (int x : nums) s += x;
170
+ if (s - target < 0 || (s - target) % 2 != 0) return 0;
171
+ target = (s - target) / 2 + 1;
172
+ vector<int > dp(target);
173
+ dp[ 0] = 1;
174
+ for (int i = 1; i < nums.size() + 1; ++i)
175
+ {
176
+ for (int j = target - 1; j >= nums[ i - 1] ; --j)
177
+ {
178
+ dp[ j] += dp[ j - nums[ i - 1]] ;
179
+ }
180
+ }
181
+ return dp[ target - 1] ;
182
+ }
183
+ };
184
+ ```
185
+
98
186
### **Go**
99
187
100
188
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -123,6 +211,29 @@ func findTargetSumWays(nums []int, target int) int {
123
211
}
124
212
```
125
213
214
+ 空间优化:
215
+
216
+ ``` go
217
+ func findTargetSumWays (nums []int , target int ) int {
218
+ s := 0
219
+ for _ , x := range nums {
220
+ s += x
221
+ }
222
+ if s-target < 0 || (s-target)%2 != 0 {
223
+ return 0
224
+ }
225
+ target = (s-target)/2 + 1
226
+ dp := make ([]int , target)
227
+ dp[0 ] = 1
228
+ for i := 1 ; i < len (nums)+1 ; i++ {
229
+ for j := target - 1 ; j >= nums[i-1 ]; j-- {
230
+ dp[j] += dp[j-nums[i-1 ]]
231
+ }
232
+ }
233
+ return dp[target-1 ]
234
+ }
235
+ ```
236
+
126
237
### ** ...**
127
238
128
239
```
0 commit comments