Leetcode494. 目標和 Python實現

  • 題目要求:

image.png
image.png

  • 思路:數組

    • 畫一個表格
    • image.png
    • 能夠求出數組中全部元素的和爲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便可
  • 要特殊注意:spa

    • 當數組的第一個元素爲0時,應初始化0的位置方法爲2,由於0+0=0,0-0=0
    • image.png
  • 核心代碼:
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]
相關文章
相關標籤/搜索