leetcode学习笔记(494目标和)

135 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

来源:力扣(LeetCode) 链接:leetcode.cn/problems/ta…

494. 目标和

给你一个整数数组 nums 和一个整数 target 。向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:
输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 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
+1 + 1 + 1 + 1 - 1 = 3

示例 2:
输入:nums = [1], target = 1
输出:1
提示:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000

代码

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        if (sum(nums)-target) % 2 != 0 or sum(nums)-target < 0:
            return 0
        neg = (sum(nums)-target) // 2 
        n = len(nums)
        
        # 转化成和昨天的题一样
        dp = [[0]*(neg+1) for _ in range(n+1)]
        dp[0][0] = 1
        for i in range(1,n+1):
            for j in range(neg+1):
                if j >= nums[i-1]:
                    dp[i][j] = dp[i-1][j]+dp[i-1][j-nums[i-1]]
                else:
                    dp[i][j] = dp[i-1][j]
        return dp[-1][-1]

解析

直接看题目感觉好难,然后看了别人的解法,转化成数组里的数可以抽出几组等于neg(neg = (sum(nums)-target) // 2),也就是说除了组成target之外的数,是否可以转化成等和子集。这道题其实就是昨天写的那道题的变形,算是换了一种问法,本质还是不变的。但是看出来是变形算是这道题的难点吧!
具体方法:
1.全部加和小于target时直接结束,全部加和减target剩下的数是奇数时也直接结束 2.转化成找和为sum(nums)-target)//2的子集数(方法类似昨天的题)