题目
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
示例:
输入:nums: [1, 1, 1, 1, 1], S: 3
输出:5
解释:
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
一共有5种方法让最终目标和为3。
```
提示:
数组非空,且长度不会超过 20 。
初始的数组的和不会超过 1000 。
保证返回的最终结果能被 32 位整数存下。
## 解题思路
def findTargetSumWays(self, nums: [int], S: int) -> int:
# #递归 超时
# if len(nums) == 1:
# if (nums[0] == S) or (-nums[0] == S):
# return 1
# else:
# return 0
# if len(nums) == 2:
# ret = 0
# if (nums[0] + nums[1]) == S:
# ret = ret + 1
# if (nums[0] - nums[1]) == S:
# ret = ret + 1
# if (-nums[0] + nums[1]) == S:
# ret = ret + 1
# if (-nums[0] - nums[1]) == S:
# ret = ret + 1
# return ret
# ret = self.findTargetSumWays(nums[:-1], S + nums[-1]) + self.findTargetSumWays(nums[:-1], S - nums[-1])
# return ret
#动态规划 背包问题,f[i] = f[i-1]+f[i+1]
dataList = [{}for j in range(len(nums)+1)]#建立数据结构存储S对应的答案
return self.findTargetSumWaysCore(nums, S, dataList)
def findTargetSumWaysCore(self, nums: [int], S: int, dataList:[int]) -> int:
SDict = dataList[len(nums)]
SStr = str(S)
if SStr in SDict:
# print("{} {} {}".format(nums,S, dataList[len(nums)][S]))
return SDict[SStr]
else:
if len(nums) == 1:
if (nums[0] == S) or (-nums[0] == S):
dataList[len(nums)][SStr] = 1
return 1
else:
return 0
if len(nums) == 2:
ret = 0
if (nums[0] + nums[1]) == S:
ret = ret + 1
if (nums[0] - nums[1]) == S:
ret = ret + 1
if (-nums[0] + nums[1]) == S:
ret = ret + 1
if (-nums[0] - nums[1]) == S:
ret = ret + 1
dataList[len(nums)][SStr] = ret
return ret
ret = self.findTargetSumWaysCore(nums[:-1], S + nums[-1], dataList) + self.findTargetSumWaysCore(nums[:-1], S - nums[-1], dataList)
dataList[len(nums)][SStr] = ret
return ret