❗️❗️❗️LeetCode 494 Medium 目標之和 Python

def findTargetSumWays(self, nums, S):
    """
    HuaHuaJiang's Method
    算法:動規
    元素和是nums_sum,整個數組的元素取值範圍就是[-nums_sum,+nums_sum],所以總共可能有的狀態值就是2*nums_sum+1
    因爲列表下標都是正的,所以設定一個offset,
    如[1,1,1,1,1],取值範圍是[-5,-4,-3,-2,-1,0,1,2,3,4,5],那麼0那個位置的下標其實是5,所以offset=nums_sum
    dp[i][j]代表前i個元素構成j有幾種方式
    dp第一維的大小是n+1,這樣就可以把dp[0]用上,代表一個元素都不用的情況
    然後底下就是for循環了,如果dp[i][j] != 0的話,那麼:
        如果加上nums[i],那麼下一行的dp[i+1][j+nums[i]] += dp[i][j],就是多了從dp[i][j]來的次數
        如果減去nums[i],那麼下一行的dp[i+1][j-nums[i]] += dp[i][j],就是多了從dp[i][j]來的次數
    這樣便可以從上向下依次推出dp[i][j]的值
    最後返回的是dp[n][S+offset],要補上offset,因爲數組下標實際上不是目標值,加上offset後纔是

    然後可以看到dp[i]之和dp[i-1]有關係,所以第一維可以去掉,使用滾動數組,將二維dp數組化爲一維dp數組
    """
    nums_sum = sum(nums)
    offset = nums_sum

    if nums_sum < S:
        return 0
    n = len(nums)
    dp = [[0] * (2 * nums_sum + 1) for _ in range(n + 1)]
    dp[0][offset] = 1

    for i in range(n):
        for j in range(2 * nums_sum + 1):
            if dp[i][j] != 0:
                dp[i + 1][j + nums[i]] += dp[i][j]
                dp[i + 1][j - nums[i]] += dp[i][j]

    return dp[n][S + offset]
def findTargetSumWays1(self, nums, S):
    """
    Brute Force Method
    Python TLE Java Accepted
    就遞歸,對每個元素進行加或者是減,看看最後到path末端的時候,和是S的話,ans += 1
    """
    self.ans = 0

    def dfs(index, path_sum):
        if index == len(nums):
            if path_sum == S:
                self.ans += 1
            return
        dfs(index + 1, path_sum + nums[index])
        dfs(index + 1, path_sum + -nums[index])

    dfs(0, 0)
    return self.ans

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章