代码随想录算法训练营第四十二天
416. 分割等和子集
代码
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2022.12
# @Author : hello algorithm!
# @Note : https://leetcode.cn/problems/partition-equal-subset-sum/
from typing import List
class Solution:
"""
dp[i][j] 表示前0-i个物品装满容量为j的背包,最大价值
递推公式:
dp[i][j] = max(dp[i-1][j-nums[i]] + nums[i],dp[i-1][j])
"""
def canPartitionV1(self, nums: List[int]) -> bool:
nums_sum = sum(nums)
if nums_sum % 2:
return False
target = nums_sum // 2
# 1. 初始化二维数组
dp = [[0 for _ in range(target + 1)] for _ in range(len(nums))]
# 2. 初始化边界条件
for i in range(target + 1):
if i >= nums[0]:
dp[0][i] = nums[0]
# 3. 遍历
for i in range(1, len(nums)):
for j in range(target + 1):
if j >= nums[i]:
dp[i][j] = max(dp[i - 1][j - nums[i]] + nums[i], dp[i - 1][j])
else:
dp[i][j] = dp[i - 1][j]
if dp[-1][-1] == target:
return True
return False
def canPartition(self, nums: List[int]) -> bool:
"""
递推公式: dp[j] = max(dp[j-nums[i]] + nums[i],dp[j])
:param nums:
:return:
"""
nums_sum = sum(nums)
if nums_sum % 2:
return False
target = nums_sum // 2
# 1. 初始化二维数组
dp = [0 for _ in range(target + 1)]
# 2. 从后往前遍历背包
for i in range(len(nums)):
for j in range(target, 0, -1):
if j >= nums[i]:
dp[j] = max(dp[j - nums[i]] + nums[i], dp[j])
return dp[target] == target
if __name__ == '__main__':
nums = [1, 5, 10, 6]
s = Solution()
print(s.canPartition(nums))