33
33
34
34
## Solutions
35
35
36
- Dynamic programming. It is similar to the 0-1 Knapsack problem.
37
-
38
36
<!-- tabs:start -->
39
37
40
38
### ** Python3**
41
39
42
40
``` python
43
41
class Solution :
44
42
def canPartition (self , nums : List[int ]) -> bool :
45
- s = sum (nums)
46
- if s % 2 != 0 :
47
- return False
48
- m, n = len (nums), s >> 1
49
- dp = [[False ] * (n + 1 ) for _ in range (m + 1 )]
50
- dp[0 ][0 ] = True
51
- for i in range (1 , m + 1 ):
52
- for j in range (n + 1 ):
53
- dp[i][j] = dp[i - 1 ][j]
54
- if not dp[i][j] and nums[i - 1 ] <= j:
55
- dp[i][j] = dp[i - 1 ][j - nums[i - 1 ]]
56
- return dp[- 1 ][- 1 ]
57
- ```
58
-
59
- ``` python
60
- class Solution :
61
- def canPartition (self , nums : List[int ]) -> bool :
62
- s = sum (nums)
63
- if s % 2 != 0 :
43
+ m, mod = divmod (sum (nums), 2 )
44
+ if mod:
64
45
return False
65
- n = s >> 1
66
- dp = [False ] * (n + 1 )
67
- dp [0 ] = True
68
- for v in nums:
69
- for j in range (n, v - 1 , - 1 ):
70
- dp[ j] = dp[ j] or dp[ j - v]
71
- return dp[ - 1 ]
46
+ n = len (nums)
47
+ f = [[ False ] * (m + 1 ) for _ in range ( n + 1 )]
48
+ f[ 0 ] [0 ] = True
49
+ for i, x in enumerate ( nums, 1 ) :
50
+ for j in range (m + 1 ):
51
+ f[i][ j] = f[i - 1 ][ j] or (j >= x and f[i - 1 ][ j - x])
52
+ return f[n][m ]
72
53
```
73
54
74
55
``` python
75
56
class Solution :
76
57
def canPartition (self , nums : List[int ]) -> bool :
77
- s = sum (nums)
78
- if s % 2 != 0 :
58
+ m, mod = divmod ( sum (nums), 2 )
59
+ if mod :
79
60
return False
80
- target = s >> 1
81
-
82
- @cache
83
- def dfs (i , s ):
84
- nonlocal target
85
- if s > target or i >= len (nums):
86
- return False
87
- if s == target:
88
- return True
89
- return dfs(i + 1 , s) or dfs(i + 1 , s + nums[i])
90
-
91
- return dfs(0 , 0 )
61
+ f = [True ] + [False ] * m
62
+ for x in nums:
63
+ for j in range (m, x - 1 , - 1 ):
64
+ f[j] = f[j] or f[j - x]
65
+ return f[m]
92
66
```
93
67
94
68
### ** Java**
95
69
96
70
``` java
97
71
class Solution {
98
72
public boolean canPartition (int [] nums ) {
73
+ // int s = Arrays.stream(nums).sum();
99
74
int s = 0 ;
100
- for (int v : nums) {
101
- s += v ;
75
+ for (int x : nums) {
76
+ s += x ;
102
77
}
103
- if (s % 2 != 0 ) {
78
+ if (s % 2 == 1 ) {
104
79
return false ;
105
80
}
106
- int m = nums. length;
107
- int n = s >> 1 ;
108
- boolean [][] dp = new boolean [m + 1 ][n + 1 ];
109
- dp[0 ][0 ] = true ;
110
- for (int i = 1 ; i <= m; ++ i) {
111
- for (int j = 0 ; j <= n; ++ j) {
112
- dp[i][j] = dp[i - 1 ][j];
113
- if (! dp[i][j] && nums[i - 1 ] <= j) {
114
- dp[i][j] = dp[i - 1 ][j - nums[i - 1 ]];
115
- }
81
+ int n = nums. length;
82
+ int m = s >> 1 ;
83
+ boolean [][] f = new boolean [n + 1 ][m + 1 ];
84
+ f[0 ][0 ] = true ;
85
+ for (int i = 1 ; i <= n; ++ i) {
86
+ int x = nums[i - 1 ];
87
+ for (int j = 0 ; j <= m; ++ j) {
88
+ f[i][j] = f[i - 1 ][j] || (j >= x && f[i - 1 ][j - x]);
116
89
}
117
90
}
118
- return dp[m][n ];
91
+ return f[n][m ];
119
92
}
120
93
}
121
94
```
122
95
123
96
``` java
124
97
class Solution {
125
98
public boolean canPartition (int [] nums ) {
99
+ // int s = Arrays.stream(nums).sum();
126
100
int s = 0 ;
127
- for (int v : nums) {
128
- s += v ;
101
+ for (int x : nums) {
102
+ s += x ;
129
103
}
130
- if (s % 2 != 0 ) {
104
+ if (s % 2 == 1 ) {
131
105
return false ;
132
106
}
133
- int n = s >> 1 ;
134
- boolean [] dp = new boolean [n + 1 ];
135
- dp [0 ] = true ;
136
- for (int v : nums) {
137
- for (int j = n ; j >= v ; -- j) {
138
- dp [j] = dp[j] || dp[j - v ];
107
+ int m = s >> 1 ;
108
+ boolean [] f = new boolean [m + 1 ];
109
+ f [0 ] = true ;
110
+ for (int x : nums) {
111
+ for (int j = m ; j >= x ; -- j) {
112
+ f [j] |= f[j - x ];
139
113
}
140
114
}
141
- return dp[n ];
115
+ return f[m ];
142
116
}
143
117
}
144
118
```
@@ -150,17 +124,21 @@ class Solution {
150
124
public:
151
125
bool canPartition(vector<int >& nums) {
152
126
int s = accumulate(nums.begin(), nums.end(), 0);
153
- if (s % 2 != 0) return false;
154
- int m = nums.size(), n = s >> 1;
155
- vector<vector<bool >> dp(m + 1, vector<bool >(n + 1));
156
- dp[ 0] [ 0 ] = true;
157
- for (int i = 1; i <= m; ++i) {
158
- for (int j = 0; j <= n; ++j) {
159
- dp[ i] [ j ] = dp[ i - 1] [ j ] ;
160
- if (!dp[ i] [ j ] && nums[ i - 1] <= j) dp[ i] [ j ] = dp[ i - 1] [ j - nums[ i - 1]] ;
127
+ if (s % 2 == 1) {
128
+ return false;
129
+ }
130
+ int n = nums.size();
131
+ int m = s >> 1;
132
+ bool f[ n + 1] [ m + 1 ] ;
133
+ memset(f, false, sizeof(f));
134
+ f[ 0] [ 0 ] = true;
135
+ for (int i = 1; i <= n; ++i) {
136
+ int x = nums[ i - 1] ;
137
+ for (int j = 0; j <= m; ++j) {
138
+ f[ i] [ j ] = f[ i - 1] [ j ] || (j >= x && f[ i - 1] [ j - x ] );
161
139
}
162
140
}
163
- return dp [ m ] [ n ] ;
141
+ return f [ n ] [ m ] ;
164
142
}
165
143
};
166
144
```
@@ -170,14 +148,19 @@ class Solution {
170
148
public:
171
149
bool canPartition(vector<int>& nums) {
172
150
int s = accumulate(nums.begin(), nums.end(), 0);
173
- if (s % 2 != 0) return false;
174
- int n = s >> 1;
175
- vector<bool> dp(n + 1);
176
- dp[0] = true;
177
- for (int& v : nums)
178
- for (int j = n; j >= v; --j)
179
- dp[j] = dp[j] || dp[j - v];
180
- return dp[n];
151
+ if (s % 2 == 1) {
152
+ return false;
153
+ }
154
+ int m = s >> 1;
155
+ bool f[m + 1];
156
+ memset(f, false, sizeof(f));
157
+ f[0] = true;
158
+ for (int& x : nums) {
159
+ for (int j = m; j >= x; --j) {
160
+ f[j] |= f[j - x];
161
+ }
162
+ }
163
+ return f[m];
181
164
}
182
165
};
183
166
```
@@ -187,48 +170,88 @@ public:
187
170
``` go
188
171
func canPartition (nums []int ) bool {
189
172
s := 0
190
- for _ , v := range nums {
191
- s += v
173
+ for _ , x := range nums {
174
+ s += x
192
175
}
193
- if s%2 != 0 {
176
+ if s%2 == 1 {
194
177
return false
195
178
}
196
- m , n := len (nums), s>>1
197
- dp := make ([][]bool , m +1 )
198
- for i := range dp {
199
- dp [i] = make ([]bool , n +1 )
179
+ n , m := len (nums), s>>1
180
+ f := make ([][]bool , n +1 )
181
+ for i := range f {
182
+ f [i] = make ([]bool , m +1 )
200
183
}
201
- dp[0 ][0 ] = true
202
- for i := 1 ; i <= m; i++ {
203
- for j := 0 ; j < n; j++ {
204
- dp[i][j] = dp[i-1 ][j]
205
- if !dp[i][j] && nums[i-1 ] <= j {
206
- dp[i][j] = dp[i-1 ][j-nums[i-1 ]]
207
- }
184
+ f[0 ][0 ] = true
185
+ for i := 1 ; i <= n; i++ {
186
+ x := nums[i-1 ]
187
+ for j := 0 ; j <= m; j++ {
188
+ f[i][j] = f[i-1 ][j] || (j >= x && f[i-1 ][j-x])
208
189
}
209
190
}
210
- return dp[m][n ]
191
+ return f[n][m ]
211
192
}
212
193
```
213
194
214
195
``` go
215
196
func canPartition (nums []int ) bool {
216
197
s := 0
217
- for _ , v := range nums {
218
- s += v
198
+ for _ , x := range nums {
199
+ s += x
219
200
}
220
- if s%2 != 0 {
201
+ if s%2 == 1 {
221
202
return false
222
203
}
223
- n := s >> 1
224
- dp := make ([]bool , n +1 )
225
- dp [0 ] = true
226
- for _ , v := range nums {
227
- for j := n ; j >= v ; j-- {
228
- dp [j] = dp [j] || dp [j-v ]
204
+ m := s >> 1
205
+ f := make ([]bool , m +1 )
206
+ f [0 ] = true
207
+ for _ , x := range nums {
208
+ for j := m ; j >= x ; j-- {
209
+ f [j] = f [j] || f [j-x ]
229
210
}
230
211
}
231
- return dp[n]
212
+ return f[m]
213
+ }
214
+ ```
215
+
216
+ ### ** TypeScript**
217
+
218
+ ``` ts
219
+ function canPartition(nums : number []): boolean {
220
+ const s = nums .reduce ((a , b ) => a + b , 0 );
221
+ if (s % 2 === 1 ) {
222
+ return false ;
223
+ }
224
+ const n = nums .length ;
225
+ const m = s >> 1 ;
226
+ const f: boolean [][] = Array (n + 1 )
227
+ .fill (0 )
228
+ .map (() => Array (m + 1 ).fill (false ));
229
+ f [0 ][0 ] = true ;
230
+ for (let i = 1 ; i <= n ; ++ i ) {
231
+ const x = nums [i - 1 ];
232
+ for (let j = 0 ; j <= m ; ++ j ) {
233
+ f [i ][j ] = f [i - 1 ][j ] || (j >= x && f [i - 1 ][j - x ]);
234
+ }
235
+ }
236
+ return f [n ][m ];
237
+ }
238
+ ```
239
+
240
+ ``` ts
241
+ function canPartition(nums : number []): boolean {
242
+ const s = nums .reduce ((a , b ) => a + b , 0 );
243
+ if (s % 2 === 1 ) {
244
+ return false ;
245
+ }
246
+ const m = s >> 1 ;
247
+ const f: boolean [] = Array (m + 1 ).fill (false );
248
+ f [0 ] = true ;
249
+ for (const x of nums ) {
250
+ for (let j = m ; j >= x ; -- j ) {
251
+ f [j ] = f [j ] || f [j - x ];
252
+ }
253
+ }
254
+ return f [m ];
232
255
}
233
256
```
234
257
@@ -240,23 +263,45 @@ func canPartition(nums []int) bool {
240
263
* @return {boolean}
241
264
*/
242
265
var canPartition = function (nums ) {
243
- let s = 0 ;
244
- for (let v of nums) {
245
- s += v;
266
+ const s = nums .reduce ((a , b ) => a + b, 0 );
267
+ if (s % 2 === 1 ) {
268
+ return false ;
269
+ }
270
+ const n = nums .length ;
271
+ const m = s >> 1 ;
272
+ const f = Array (n + 1 )
273
+ .fill (0 )
274
+ .map (() => Array (m + 1 ).fill (false ));
275
+ f[0 ][0 ] = true ;
276
+ for (let i = 1 ; i <= n; ++ i) {
277
+ const x = nums[i - 1 ];
278
+ for (let j = 0 ; j <= m; ++ j) {
279
+ f[i][j] = f[i - 1 ][j] || (j >= x && f[i - 1 ][j - x]);
280
+ }
246
281
}
247
- if (s % 2 != 0 ) {
282
+ return f[n][m];
283
+ };
284
+ ```
285
+
286
+ ``` js
287
+ /**
288
+ * @param {number[]} nums
289
+ * @return {boolean}
290
+ */
291
+ var canPartition = function (nums ) {
292
+ const s = nums .reduce ((a , b ) => a + b, 0 );
293
+ if (s % 2 === 1 ) {
248
294
return false ;
249
295
}
250
- const m = nums .length ;
251
- const n = s >> 1 ;
252
- const dp = new Array (n + 1 ).fill (false );
253
- dp[0 ] = true ;
254
- for (let i = 1 ; i <= m; ++ i) {
255
- for (let j = n; j >= nums[i - 1 ]; -- j) {
256
- dp[j] = dp[j] || dp[j - nums[i - 1 ]];
296
+ const m = s >> 1 ;
297
+ const f = Array (m + 1 ).fill (false );
298
+ f[0 ] = true ;
299
+ for (const x of nums) {
300
+ for (let j = m; j >= x; -- j) {
301
+ f[j] = f[j] || f[j - x];
257
302
}
258
303
}
259
- return dp[n ];
304
+ return f[m ];
260
305
};
261
306
```
262
307
0 commit comments