清单
● 416. 分割等和子集
LeetCode #46 分割等和子集
1. 题目
给你一个只包含正整数的非空数组 nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
2. 思路
若 sum(nums) % 2 != 0, 则 return False, 将问题转化为背包问题。
当 dp[target] == target时,return True
- dp数组含义: 背包i所能承载的最大子集和为dp[i]
- 递推公式: dp[i] = max(dp[i], dp[j-i] + i)
- 初始化数组: 考虑极端情况,当数组内元素全为1时,最多循环target = sum(nums) // 2 次,len(dp) = [0] * (target + 1)
- 确认遍历顺序: 若正序遍历, dp[i] 会累加 不满足要求,采用倒叙遍历
3. 代码实现
class Solution:
def canPartition(self, nums: List[int]) -> bool:
#Exclude Special Cases
if sum(nums) % 2 != 0:
return False
target = sum(nums) // 2
#Initialize dp
dp = [0] * (target + 1)
for num in nums:
for j in range(target,num - 1, -1):
dp[j] = max(dp[j], dp[j-num] + num)
return dp[-1] == target