题解
思路
代码
class Solution:
### 0106 动态规划(712 ms,17.1 MB)
def findTargetSumWays(self, nums: List[int], S: int) -> int:
# 初始化计算非负数组的总和
total_sum, n = sum(nums), len(nums)
# 定义二维动态规划数组dp,int型的默认字典
# dp[i][j]表示前i个数的总和为j的总方案数量
dp = [collections.defaultdict(int) for _ in range(n)]
# 初始化数组中第一个值的方案数量(正、负两种情况)
dp[0][nums[0]] = 1
dp[0][-nums[0]] += 1 # 这里使用+=是为了处理nums[0]等于0的情况
# 从第二个数开始遍历,进行动态规划
for i in range(1, n):
num = nums[i]
# 每取一个数,遍历数组总和的每一种情况
for j in range(-total_sum, total_sum + 1):
dp[i][j] = dp[i - 1].get(j - num, 0) + dp[i - 1].get(j + num, 0)
return dp[-1][S] # 返回数组中全部元素求和为S的情况
### 0106 动态规划 + 空间优化(632 ms,15.2 MB)
def findTargetSumWays(self, nums: List[int], S: int) -> int:
total_sum, n = sum(nums), len(nums)
# 定义一维动态规划数组dp,int型的默认字典
# dp[j]表示数组中全部元素的总和为j的总方案数量
dp = collections.defaultdict(int)
dp[nums[0]] = 1
dp[-nums[0]] += 1 # 这里使用+=是为了处理nums[0]等于0的情况
# 注意:从第二个数开始遍历,否则会造成全0情况!
for i in range(1, n):
num = nums[i]
# 对于每一个数,新建一个动态规划字典
tmp_dp = collections.defaultdict(int)
for j in range(-total_sum, total_sum + 1):
tmp_dp[j] = dp.get(j - num, 0) + dp.get(j + num, 0)
dp = tmp_dp # 使用本轮的tmp_dp更新dp
return dp[S] # 返回数组中全部元素的总和为S的情况