https://leetcode.com/problems/target-sum/
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols +
and -
. For each integer, you should choose one from +
and -
as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: -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 There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- Your output answer is guaranteed to be fitted in a 32-bit integer.
使用两种方法,一种为递归的方法,另一种为动态规划的方法,递归的方法会过不了oj,动态规划的方法可以。
使用1D dp的方法需要不断更新dp数组,保存当前可能的sum值以及对应的解法数量,如果遍历到最后,还没有等于sum值对应的dp[sum]依然为0说明没有解法。
class Solution(object):
count = 0
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
self.findTargetSum(nums, 0, 0, S)
return self.count
def findTargetSum(self, nums, start, s, S):
if start == len(nums):
if(s == S):
self.count += 1
else:
self.findTargetSum(nums, start + 1, s + nums[start], S)
self.findTargetSum(nums, start + 1, s - nums[start], S)
class Solution(object):
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
dp = [0 for _ in range(2001)]
dp[nums[0] + 1000] = 1
dp[-nums[0] + 1000] += 1
for i in range(1, len(nums)):
next = [0] * 2001
for sum in range(-1000, 1001):
if dp[sum + 1000] > 0 :
next[sum + nums[i] + 1000] += dp[sum + 1000]
next[sum - nums[i] + 1000] += dp[sum + 1000]
dp = next
if S > 1000:
return 0
else:
return dp[S+1000]
if __name__ == "__main__":
nums = [1, 1, 1, 1, 1]
solution = Solution()
print(solution.findTargetSumWays(nums, 3))