R3-dp篇.
目录
思路:
增加记忆化搜索:
优化空间复杂度:
思路:
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
#设正数之和为p,总元素之和为s,带符号总元素之和为t,则p-(s-p)=t
#p=(s+t)/2
#则(s+t)>0且不为奇数
target+=sum(nums)
if target<0 or target%2:
return 0
#现在target代表选n个数之和为target
target//=2
n=len(nums)
#i为下标,c为和
def dfs(i,c):
if i<0:
return 1 if c==0 else 0
if c<nums[i]:
return dfs(i-1,c)
#求总组合数,就直接相加(01背包问题返回max值)
return dfs(i-1,c)+dfs(i-1,c-nums[i])
return dfs(n-1,target)
增加记忆化搜索:
@cache
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
#设正数之和为p,总元素之和为s,带符号总元素之和为t,则p-(s-p)=t
#p=(s+t)/2
#则(s+t)>0且不为奇数
target+=sum(nums)
if target<0 or target%2:
return 0
#现在target代表选n个数之和为target
target//=2
n=len(nums)
#i为下标,c为和
@cache
def dfs(i,c):
if i<0:
return 1 if c==0 else 0
if c<nums[i]:
return dfs(i-1,c)
#求总组合数,就直接相加(01背包问题返回max值)
return dfs(i-1,c)+dfs(i-1,c-nums[i])
return dfs(n-1,target)
优化空间复杂度:
将记忆化搜索改为1比1的递推式,翻译成f函数
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
#设正数之和为p,总元素之和为s,带符号总元素之和为t,则p-(s-p)=t
#p=(s+t)/2
#则(s+t)>0且不为奇数
target+=sum(nums)
if target<0 or target%2:
return 0
#现在target代表选n个数之和为target
target//=2
n=len(nums)
#递推数组的建立
f=[[0]*(target+1) for _ in range(n+1)]
#初始化,即刚刚的i,c==0
f[0][0]=1
for i,x in enumerate(nums):
for c in range(target+1):
if c<x:
f[i+1][c]=f[i][c]
else:
f[i+1][c]=f[i][c]+f[i][c-x]
return f[n][target]
ps:
灵神优化方法(时间,空间上)
01背包记忆化搜索
灵神学习路线:二叉树递归 -> 回溯 -> 记忆化搜索 -> 递推