整数和是p,负数和是s-p,那么target = p - (s-p),求出p = (s+t)//2
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2: #target 一定是偶数而且是大于0
return 0
target = target // 2
n = len(nums)
@cache #cache是将传参和返回记录下来,避免了重复计算
def dfs(i,c):
if i < 0:
return 1 if c == 0 else 0 #如果c小于0,那就没有找到,返回0,c==0返回1
if nums[i] > c: #当前值大于c,不能选
return dfs(i-1,c)
return dfs(i-1,c)+dfs(i-1,c-nums[i]) #返回选或者不选的和
return dfs(n-1,target)
改成递推的形式
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2:
return 0
target = target // 2
n = len(nums)
dp = [[0]*(target+1) for i in range(n+1)]
dp[0][0] = 1 #初始化
for i,x in enumerate(nums):
for c in range(target+1):
if c < x: #不选
dp[i+1][c] = dp[i][c]
else: #选+不选
dp[i+1][c] = dp[i][c] + dp[i][c-x]
return dp[-1][-1]
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
#完全背包,对于完全背包,每次选择之后,还可以继续选。
n = len(coins)
@cache
def dfs(i,c):
if i < 0:
return 0 if c == 0 else inf #如果当前不满足条件就返回无穷
if c < coins[i]: #不选
return dfs(i-1,c)
return min(dfs(i-1,c),dfs(i,c-coins[i])+1) #选的时候不能是i-1,因为选了可以再选
a = dfs(n-1,amount)
return a if a < inf else -1
改成递推的形式
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
n = len(coins)
dp = [[inf]*(amount+1) for i in range(n+1)]
dp[0][0] = 0
for i,x in enumerate(coins):
for c in range(amount+1):
if x > c:
dp[i+1][c] = dp[i][c] #不选,往下走
else:
dp[i+1][c] =min(dp[i][c],dp[i+1][c-x]+1) #选了还可以继续选i+1
ans = dp[-1][-1]
return ans if ans < inf else -1
在例题494中,如果是至多是target。那就在边界条件时不需要判断,初始化dp全部为1.
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2:
return 0
target = target // 2
n = len(nums)
dp = [[1]*(target+1) for i in range(n+1)]
for i,x in enumerate(nums):
for c in range(target+1):
if c < x: #不选
dp[i+1][c] = dp[i][c]
else: #选+不选
dp[i+1][c] = dp[i][c] + dp[i][c-x]
return dp[-1][-1]
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2: #target 一定是偶数而且是大于0
return 0
target = target // 2
n = len(nums)
@cache #cache是将传参和返回记录下来,避免了重复计算
def dfs(i,c):
if i < 0:
return 1
if nums[i] > c: #当前值大于c,不能选
return dfs(i-1,c)
return dfs(i-1,c)+dfs(i-1,c-nums[i]) #返回选或者不选的和
return dfs(n-1,target)
如果是至少为target,那就是比target大也可以。
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2: #target 一定是偶数而且是大于0
return 0
target = target // 2
n = len(nums)
@cache #cache是将传参和返回记录下来,避免了重复计算
def dfs(i,c):
if i < 0:
return 1 if c <= 0 else 0
return dfs(i-1,c)+dfs(i-1,c-nums[i]) #不会判断nums[i]>c的情况
return dfs(n-1,target)