给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
开始我想的是用一个类似于贪心算法的办法,算出相加和除以2为sum以后,只需要找出一些数字能让他的结果等于sum就可以证明,但是让sum从最大值开始减去,如果能为0就可以.代码如下
class Solution:
def canPartition(self, nums: List[int]) -> bool:
if not nums:
return False
s=sum(nums)
if s%2!=0:
return False
summ=s/2
nums.sort(reverse=True)
i=0
while i!=len(nums):
if nums[i]<=summ:
summ=summ-nums[i]
if summ==0:
return True
i=i+1
return False
但是显然存在反例 比如 6 5 4 3 3 3 用这个办法就无法得到结果.
那么我们想到另一个办法,因为他只需要返回true或者false,只需要判断存不存在就可以,可以列出所有可能存在的值,为了减少运算超过sum的不管,只要存在sum就说明可以是true.这里如果是我,我会运用hash表的办法,但是并不是很好搞. 正确答案如下
def canPartition(self, nums: List[int]) -> bool:
total = sum(nums)
if total % 2 != 0:
return False
target = total // 2
dp = [False] * (target + 1)
dp[0] = True
for num in nums:
for j in range(target, num - 1, -1):
dp[j] = dp[j] or dp[j - num]
return dp[target]
用了一个类似于反向的办法,跟点星星一样,如果存在就点亮,对于任意一个j来说,如果它本身就是存在过的,或者它减去num的那个值存在过,那么这个j就应该存在.