LeetCode Hot 100-416分割等和子集

给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
每个数组中的元素不会超过 100
数组的大小不会超过 200
示例 1:
输入: [1, 5, 11, 5]
输出: true
解释: 数组可以分割成 [1, 5, 5] 和 [11].
示例 2:
输入: [1, 2, 3, 5]
输出: false
解释: 数组不能分割成两个元素和相等的子集.

动态规划,首先有一些细节的点:

  • 所有的元素加起来不会超过20000
  • 如果和为奇数,不可能会分成两个相同的数相加
  • dp[i][j]表示:在[0,i]的区间,这个子区间内挑选一些正整数,每个数只能用一次,使得这些数的和等于 j
  • 状态转移方程
    • 如果不选择nums[i],在[0, i - 1]这个子区间内已经有一部分元素,使得它们的和为j ,那么dp[i][j] = true;
    • 如果选择nums[i],在[0, i - 1]这个子区间内就得找到一部分元素,使得它们的和为j - nums[i] ,我既然这样写出来了,你就应该知道,这里讨论的前提条件是nums[i] <= j。
    • dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i]] (j >= nums[i])
    • dp[i][j] = dp[i - 1][j](j < nums[i])

代码

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        s = sum(nums)
        if s % 2 == 1:
            return False
        target = int(s / 2)
        dp = [[False for _ in range(target + 1)] for _ in range(len(nums))]

        for i in range(len(dp[0])):
            dp[0][i] = False if nums[0] != i else True

        for i in range(1, len(nums)):
            for j in range(target + 1):
                if j >= nums[i]:
                    dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i]]
                else:
                    dp[i][j] = dp[i - 1][j]
        return dp[-1][-1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-equal-subset-sum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值