day42 动态规划part4 代码随想录算法训练营 416. 分割等和子集

题目:416. 分割等和子集

我的感悟:

  • 有点难,
  • 更快的解法用了01 True 和False 所以更快

理解难点:

  • 转化为背包问题

听课笔记:

代码示例:我优化了下

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        if sum(nums) % 2 == 1:
            return False
        target = sum(nums) // 2

        # dp[i]中的i表示背包内总和
        # 题目中说:每个数组中的元素不会超过 100,数组的大小不会超过 200
        # 总和不会大于20000,背包最大只需要其中一半,所以10001大小就可以了
        dp = [0] * (target+1)

        # 开始 0-1背包
        for i in range(len(nums)):
            for j in range(target, nums[i] - 1, -1):  # 每一个元素一定是不可重复放入,所以倒序遍历
                dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
                if dp[j] == target:
                    return True
                if dp[j] > target:
                    return False
        # 集合中的元素正好可以凑成总和target
        # if dp[target] == target:
        #     return True
        return False

通过截图:

扩展写法(这个更快):

class Solution:
    def canPartition(self, nums: List[int]) -> bool:

        total_sum = sum(nums)

        if total_sum % 2 != 0:
            return False

        target_sum = total_sum // 2
        dp = [False] * (target_sum + 1)
        dp[0] = True

        for num in nums:
            # 从target_sum逆序迭代到num,步长为-1
            for i in range(target_sum, num - 1, -1):
                dp[i] = dp[i] or dp[i - num]
        return dp[target_sum]

资料:

  1. 分割等和子集  

本题是 01背包的应用类题目

https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html

视频讲解:https://www.bilibili.com/video/BV1rt4y1N7jE

posted @ 2024-02-26 21:16  o蹲蹲o  阅读(7)  评论(0编辑  收藏  举报