【LeetCode 中等题】75-分割等和子集

题目描述:给定一个只包含正整数非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

注意:

  1. 每个数组中的元素不会超过 100
  2. 数组的大小不会超过 200

示例 1:

输入: [1, 5, 11, 5]

输出: true

解释: 数组可以分割成 [1, 5, 5] 和 [11].

示例 2:

输入: [1, 2, 3, 5]

输出: false

解释: 数组不能分割成两个元素和相等的子集.

解法1。这是个典型的背包问题,能不能找到若干各元素使其和等于sum/2(sum必须是可均分的,不然返回False)。

class Solution(object):
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        if not nums:
            return False
        summ = sum(nums)
        if summ & 1:
            return False
        memo = [[-1 for _ in range(summ//2+1)] for _ in range(len(nums))]
        return self.helper(nums, 0, summ//2, memo)
    
    def helper(self, nums, index, summ, memo):
        if summ == 0:
            return True    
        if index >= len(nums) or summ < 0:
            return False
        if memo[index][summ] != -1:
            return memo[index][summ] == 1
        if self.helper(nums, index+1, summ, memo) or self.helper(nums, index+1, summ-nums[index], memo):
            memo[index][summ] = 1
        else:
            memo[index][summ] = 0
        return memo[index][summ] == 1

解法2。改写成DP,自底向上

class Solution(object):
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        if not nums:
            return False
        summ = sum(nums)
        if summ & 1:
            return False
        memo = [False for _ in range(summ//2+1)]
        c = summ//2
        for i in range(c+1):
            memo[i] = True if nums[0] == i else False
        for i in range(1, len(nums)):
            j=c
            while j >= nums[i]:
                memo[j] = memo[j] or memo[j-nums[i]]
                j -= 1
        return memo[-1]

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值