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

**分析:**直观的解法是用回溯法,罗列出每一种可能性,每一个数都有"+"和”-“两种情况,因此就是一个二叉树的遍历问题,求出每一个从顶点到底部路径和,记录和为target的数量。每一个数都有两种状态,共有n个数,因此时间复杂度为 2 n 2^n 2n,指数爆炸。见方法1

方法1:

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        n = len(nums)
        count = 0
        def backtrack(k, s, count):
            if k == n:
                if s == target:
                    count += 1
                return count
            for op in [-1, 1]:
                num = op*nums[k]
                count = backtrack(k+1, s+num, count)
            return count
        return backtrack(0, 0, count)

方法2: 此问题可以转化为背包问题,用DP算法求解

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        """
        假设添加“+”的元素和为pos, 添加“-”的元素和为seg, sum为list的元素和,
        有pos+seg=sum, pos-seg=target ==> pos = (sum+target)/2
        """
        n = len(nums)
        s1 = sum(nums)
        s2 = s1+target
        #pos必然为整数, 因此没有整除说明不存在满足的表达式
        if s2 % 2 != 0 or s2 < 0:
            return 0
        else:
            pos = s2 // 2
            dp = [[0]* (pos+1) for i in range(n+1)]
            dp[0][0] = 1
            for i in range(1, n+1):
                for t in range(pos+1):
                    if t < nums[i-1]:
                        dp[i][t] = dp[i-1][t]
                    else:
                        dp[i][t] = dp[i-1][t-nums[i-1]] + dp[i-1][t]
            return dp[-1][-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值