class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
# 公式推导和变量意义见答案解析。
diff = (sum(nums) - target)
if diff < 0 or diff % 2 == 1:
return 0
neg = (sum(nums)-target) // 2
'''
因为可以每个数字都不取,所以dp数组有len(nums)+1行;
初始化为dp[0][0] = 1,是对应neg==0时sum(nums)==target的情况,
此时只有nums数组所有数字都对应加号着一种情况。
'''
dp = [[0] * (neg+1) for _ in range(len(nums)+1)]
dp[0][0] = 1
for i in range(1, len(nums)+1):
for j in range(neg+1):
if nums[i-1] > j:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i-1]]
return dp[-1][-1]
01背包问题的二维dp数组,一般都可以替换成一维滚动数组,同样要注意背包遍历要倒序以防止重复添加物品。
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
diff = (sum(nums) - target)
if diff < 0 or diff % 2 == 1:
return 0
neg = (sum(nums)-target) // 2
dp = [0] * (neg+1)
dp[0] = 1
for i in range(1, len(nums)+1):
for j in range(neg, -1, -1):
if nums[i-1] > j:
dp[j] = dp[j]
else:
dp[j] = dp[j] + dp[j-nums[i-1]]
return dp[-1]