Leetcode494. 目标和 Python实现

  • 题目要求:

Leetcode494. 目标和 Python实现_第1张图片

  • 思路:

    • 画一个表格
    • Leetcode494. 目标和 Python实现_第2张图片
    • 可以求出数组中所有元素的和为5,所以画一个(5*2+1)len(nums)的表格(也就是一个二维数组)
    • -5~5表示把这个数组每一个元素加上或减去得到结果值的所有可能
    • 从[-1 -1 -1 -1 -1]到[+1 +1 +1 +1 +1]的所有可能
    • 遍历数组,当遍历到数组下标为0的元素时,也就是第一个1,它与加号减号的组合有两种:1 和 -1,所以得到-1的方法有1种,得到1的方法也有一种
    • 当遍历到数组下标为1的元素时,前面已经得到的可能的结果值为-1和1,那么在这个基础上,新加入新的1与加号减号的组合,可能得到-2(-1-1),可能得到0(-1+1或+1-1),可能得到2(+1+1),所以在-2的位置有一种方法,在0的位置有2种,在1的位置有1种
    • 依次遍历,遍历到最后,找到目标值所对应的列的最后一行,也就是3所对应的有5中方法,返回5即可
  • 要特殊注意:

    • 当数组的第一个元素为0时,应初始化0的位置方法为2,因为0+0=0,0-0=0
    • Leetcode494. 目标和 Python实现_第3张图片
  • 核心代码:
dp = [[0 for i in range(2 * total + 1)] for j in range(len(nums))]

# 如果数组的第一个元素为0,那么+0或是-0,结果都为0
if nums[0] == 0:
    dp[0][total] = 2
else:
    # total是数组元素的和,也是dp的行中,元素值为0的元素的下标
    dp[0][total + nums[0]] = 1
    dp[0][total - nums[0]] = 1

for i in range(1, len(dp)):
    for j in range(len(dp[0])):
        # 注意边界
        # 在第一个图中,dp[4][0]的当前元素值是1,对应的目标值是-5,那么-5加上或减去1可能是上一行得到的值,但是要注意-5-1也就是-6不在考虑范围内
        # left和right都初始化为0,是因为在表格也就是二维数组中,0所在的列所对应的目标值是给定数组的所有元素可能得到的最小值,是一个极值,所以不到最后一行,也就是不遍历到最后一个数组元素是得不到这个值的,也就是,所有行的下标为0的位置(所有行的起始位置)的方法数一定是0,所以当left或right越界了,没有被赋新的值时,不会影响计算方法数
        left, right = 0, 0
        if j - nums[i] >= 0:
            left = j - nums[i]
        if j + nums[i] < 2 * total + 1:
            right = j + nums[i]
        dp[i][j] = dp[i - 1][left] + dp[i - 1][right]
return dp[-1][total + S]
  • 完整代码:
class Solution:
    def findTargetSumWays(self, nums: List[int], S: int) -> int:
        total = sum(nums)
        if total < S:
            return 0
        dp = [[0 for i in range(2 * total + 1)] for j in range(len(nums))]

        if nums[0] == 0:
            dp[0][total] = 2
        else:
            dp[0][total + nums[0]] = 1
            dp[0][total - nums[0]] = 1

        for i in range(1, len(dp)):
            for j in range(len(dp[0])):
                left, right = 0, 0
                if j - nums[i] >= 0:
                    left = j - nums[i]
                if j + nums[i] < 2 * total + 1:
                    right = j + nums[i]
                dp[i][j] = dp[i - 1][left] + dp[i - 1][right]

        return dp[-1][total + S]

你可能感兴趣的:(leetcode,python)