【每日一題】組合總和 Ⅳ

377. 組合總和 Ⅳ

給你一個由 不同 整數組成的數組 nums ,和一個目標整數 target 。請你從 nums 中找出並返回總和爲 target 的元素組合的個數。

題目數據保證答案符合 32 位整數範圍。

示例 1:

輸入:nums = [1,2,3], target = 4
輸出:7
解釋:
所有可能的組合爲:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
請注意,順序不同的序列被視作不同的組合。

示例 2:

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 1000
  • nums 中的所有元素 互不相同
  • 1 <= target <= 1000

這題一開始還試圖用之前遞歸的方法做,但發現這邊需要考慮不同順序。用動態規劃遞推來做會比較簡潔。

class Solution(object):
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        dp = [0] * (target + 1) # dp[i]表示和爲i的不同組合數,初始化爲0
        dp[0] = 1 # 總和爲0的組合方式只有一種,即空集
        
        for i in range(1, target + 1): 
            for num in nums:
                if i < num:
                    break
                dp[i] += dp[i - num] # 所有和爲i-num的組合加上當前元素可以形成和爲i的新組合

        return dp[target]

代碼雖然短,但對於很久沒寫dp的人來說還是需要理解一會的。。動態規劃通過構建一個解決方案的部分問題來解決整個問題,通常涉及填充一個或多個DP表(在這個問題中,是一個一維數組)。對於這個特定問題,DP數組的每個位置 i 代表了組成和爲 i 的不同組合數。

初始化

我們初始化 dp[0] = 1。這意味着,總和爲0的組合方式只有一種,即不選擇任何數字(空集合)。這是動態規劃的基礎。

遞推關係

對於每個可能的 i(從1到 target),我們考慮所有可能的 nums 中的數字 num,如果當前數字 num 小於或等於 i,那麼 num 可以成爲一個潛在的組合部分。

我們的更新規則是 dp[i] += dp[i - num],它基於這樣的邏輯:

  • 如果你已經知道了組成和爲 i - num 的所有可能的組合數(存儲在 dp[i - num] 中),那麼每一種組合都可以通過添加 num 來形成一個新的和爲 i 的組合。
  • 因此,你可以將這些新增的組合數加到 dp[i] 上。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章