@@ -224,18 +224,79 @@ class Solution {
224
224
```
225
225
226
226
### Python:
227
+ 卡哥版
227
228
``` python
228
229
class Solution :
229
230
def lastStoneWeightII (self , stones : List[int ]) -> int :
230
- sumweight = sum (stones)
231
- target = sumweight // 2
232
- dp = [0 ] * (target + 1 )
233
- for i in range (len (stones)):
234
- for j in range (target, stones[i] - 1 , - 1 ):
235
- dp[j] = max (dp[j], dp[j - stones[i]] + stones[i])
236
- return sumweight - 2 * dp[target]
231
+ dp = [0 ] * 15001
232
+ total_sum = sum (stones)
233
+ target = total_sum // 2
234
+
235
+ for stone in stones: # 遍历物品
236
+ for j in range (target, stone - 1 , - 1 ): # 遍历背包
237
+ dp[j] = max (dp[j], dp[j - stone] + stone)
238
+
239
+ return total_sum - dp[target] - dp[target]
240
+
237
241
```
242
+ 二维DP版
243
+ ``` python
244
+ class Solution :
245
+ def lastStoneWeightII (self , stones : List[int ]) -> int :
246
+ total_sum = sum (stones)
247
+ target = total_sum // 2
248
+
249
+ # 创建二维dp数组,行数为石头的数量加1,列数为target加1
250
+ # dp[i][j]表示前i个石头能否组成总重量为j
251
+ dp = [[False ] * (target + 1 ) for _ in range (len (stones) + 1 )]
252
+
253
+ # 初始化第一列,表示总重量为0时,前i个石头都能组成
254
+ for i in range (len (stones) + 1 ):
255
+ dp[i][0 ] = True
256
+
257
+ for i in range (1 , len (stones) + 1 ):
258
+ for j in range (1 , target + 1 ):
259
+ # 如果当前石头重量大于当前目标重量j,则无法选择该石头
260
+ if stones[i - 1 ] > j:
261
+ dp[i][j] = dp[i - 1 ][j]
262
+ else :
263
+ # 可选择该石头或不选择该石头
264
+ dp[i][j] = dp[i - 1 ][j] or dp[i - 1 ][j - stones[i - 1 ]]
265
+
266
+ # 找到最大的重量i,使得dp[len(stones)][i]为True
267
+ # 返回总重量减去两倍的最接近总重量一半的重量
268
+ for i in range (target, - 1 , - 1 ):
269
+ if dp[len (stones)][i]:
270
+ return total_sum - 2 * i
271
+
272
+ return 0
273
+
238
274
275
+ ```
276
+ 一维DP版
277
+ ``` python
278
+ class Solution :
279
+ def lastStoneWeightII (self , stones ):
280
+ total_sum = sum (stones)
281
+ target = total_sum // 2
282
+ dp = [False ] * (target + 1 )
283
+ dp[0 ] = True
284
+
285
+ for stone in stones:
286
+ for j in range (target, stone - 1 , - 1 ):
287
+ # 判断当前重量是否可以通过选择之前的石头得到或选择当前石头和之前的石头得到
288
+ dp[j] = dp[j] or dp[j - stone]
289
+
290
+ for i in range (target, - 1 , - 1 ):
291
+ if dp[i]:
292
+ # 返回剩余石头的重量,即总重量减去两倍的最接近总重量一半的重量
293
+ return total_sum - 2 * i
294
+
295
+ return 0
296
+
297
+
298
+
299
+ ```
239
300
### Go:
240
301
``` go
241
302
func lastStoneWeightII (stones []int ) int {
0 commit comments