再學動態規劃之 01揹包
阿新 • • 發佈:2019-01-03
寫了之後,發現這題跟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
接下來是有趣的解法
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
意思就是 直接把可能的和加出來。。。。