leetcode: https://leetcode.com/problems/partition-equal-subset-sum/description/
写了之后,发现这题跟01背包还有点区别。但是写看这个吧。
暴力搜索的方法。就是每个取或者不去。
class Solution(object):
def getS(self, arr, index, target):
if target == 0:
return True
elif target < 0:
return False
else:
if index == len(arr)-1:
if arr[index] == target:
return True
else:
return False
else:
return self.getS(arr, index+1, target) or self.getS(arr, index+1, target-arr[index])
def canPartition(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
total = sum(nums)
if total%2 == 1:
return False
target = total/2
return self.getS(nums, 0, target)
超时是必然的。接下来,我们把目前 考虑index和目标target记录下来:
rec_dict = dict()
class Solution(object):
def getS(self, arr, index, target):
if target == 0:
return True
elif target < 0:
return False
else:
if index == len(arr)-1:
if arr[index] == target:
return True
else:
return False
else:
temp = str(index)+'_'+str(target)
if temp in rec_dict:
return rec_dict[str(index)+'_'+str(target)]
else:
rec_dict[str(index)+'_'+str(target)] = self.getS(arr, index+1, target) or self.getS(arr, index+1, target-arr[index])
return rec_dict[str(index)+'_'+str(target)]
def canPartition(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
rec_dict.clear()
total = sum(nums)
if total%2 == 1:
return False
target = total/2
return self.getS(nums, 0, target)
这下通过了。但是我们发现这里 存在众多的递归调用。这就是因为没有按顺序计算的结果。这也引入了动态规划:
class Solution(object):
def canPartition(self,nums):
"""
:type nums: List[int]
:rtype: bool
"""
total = sum(nums)
if total % 2 == 1:
return False
target = total / 2
arr = [[False for _ in range(target+1)] for _ in range(len(nums)+1)]
for ix in range(len(arr)):
arr[ix][0] = True
for i in range(1, len(nums) + 1):
for j in range(1, target + 1):
if j - nums[i - 1] >= 0:
arr[i][j] = (arr[i - 1][j - nums[i - 1]] or arr[i - 1][j])
else:
arr[i][j] = arr[i - 1][j]
if arr[i][target] == True:
return True
return False
之前用
arr = [[False]*x]*y
的方式初始化。看似很厉害,其实是错的。 详见:https://www.cnblogs.com/woshare/p/5823303.html
接下来是有趣的解法
class Solution(object):
def canPartition(self,nums):
"""
:type nums: List[int]
:rtype: bool
"""
possible_sum = {0}
for num in nums:
possible_sum.update({v+num for v in possible_sum})
return sum(nums)/2. in possible_sum
意思就是 直接把可能的和加出来。。。。
进阶:bitset! https://www.cnblogs.com/grandyang/p/5951422.html
python没有对应的写法,很让人捉急